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.
34 #include "event_nvmf.h"
36 #include "spdk/bdev.h"
40 #include "spdk/nvme.h"
41 #include "spdk/nvmf.h"
42 #include "spdk/string.h"
43 #include "spdk/util.h"
46 json_write_hex_str(struct spdk_json_write_ctx
*w
, const void *data
, size_t size
)
48 static const char hex_char
[16] = "0123456789ABCDEF";
49 const uint8_t *buf
= data
;
53 str
= malloc(size
* 2 + 1);
60 unsigned byte
= *buf
++;
62 out
[0] = hex_char
[(byte
>> 4) & 0xF];
63 out
[1] = hex_char
[byte
& 0xF];
69 rc
= spdk_json_write_string(w
, str
);
76 hex_nybble_to_num(char c
)
78 if (c
>= '0' && c
<= '9') {
82 if (c
>= 'a' && c
<= 'f') {
86 if (c
>= 'A' && c
<= 'F') {
94 hex_byte_to_num(const char *str
)
98 hi
= hex_nybble_to_num(str
[0]);
103 lo
= hex_nybble_to_num(str
[1]);
112 decode_hex_string_be(const char *str
, uint8_t *out
, size_t size
)
116 /* Decode a string in "ABCDEF012345" format to its binary representation */
117 for (i
= 0; i
< size
; i
++) {
118 int num
= hex_byte_to_num(str
);
121 /* Invalid hex byte or end of string */
125 out
[i
] = (uint8_t)num
;
129 if (i
!= size
|| *str
!= '\0') {
130 /* Length mismatch */
138 decode_ns_nguid(const struct spdk_json_val
*val
, void *out
)
143 rc
= spdk_json_decode_string(val
, &str
);
146 rc
= decode_hex_string_be(str
, out
, 16);
154 decode_ns_eui64(const struct spdk_json_val
*val
, void *out
)
159 rc
= spdk_json_decode_string(val
, &str
);
162 rc
= decode_hex_string_be(str
, out
, 8);
170 decode_ns_uuid(const struct spdk_json_val
*val
, void *out
)
175 rc
= spdk_json_decode_string(val
, &str
);
177 rc
= spdk_uuid_parse(out
, str
);
185 dump_nvmf_subsystem(struct spdk_json_write_ctx
*w
, struct spdk_nvmf_subsystem
*subsystem
)
187 struct spdk_nvmf_host
*host
;
188 struct spdk_nvmf_listener
*listener
;
190 spdk_json_write_object_begin(w
);
192 spdk_json_write_name(w
, "nqn");
193 spdk_json_write_string(w
, spdk_nvmf_subsystem_get_nqn(subsystem
));
194 spdk_json_write_name(w
, "subtype");
195 if (spdk_nvmf_subsystem_get_type(subsystem
) == SPDK_NVMF_SUBTYPE_NVME
) {
196 spdk_json_write_string(w
, "NVMe");
198 spdk_json_write_string(w
, "Discovery");
201 spdk_json_write_name(w
, "listen_addresses");
202 spdk_json_write_array_begin(w
);
204 for (listener
= spdk_nvmf_subsystem_get_first_listener(subsystem
); listener
!= NULL
;
205 listener
= spdk_nvmf_subsystem_get_next_listener(subsystem
, listener
)) {
206 const struct spdk_nvme_transport_id
*trid
;
210 trid
= spdk_nvmf_listener_get_trid(listener
);
212 spdk_json_write_object_begin(w
);
213 trtype
= spdk_nvme_transport_id_trtype_str(trid
->trtype
);
214 if (trtype
== NULL
) {
217 adrfam
= spdk_nvme_transport_id_adrfam_str(trid
->adrfam
);
218 if (adrfam
== NULL
) {
221 /* NOTE: "transport" is kept for compatibility; new code should use "trtype" */
222 spdk_json_write_name(w
, "transport");
223 spdk_json_write_string(w
, trtype
);
224 spdk_json_write_name(w
, "trtype");
225 spdk_json_write_string(w
, trtype
);
226 spdk_json_write_name(w
, "adrfam");
227 spdk_json_write_string(w
, adrfam
);
228 spdk_json_write_name(w
, "traddr");
229 spdk_json_write_string(w
, trid
->traddr
);
230 spdk_json_write_name(w
, "trsvcid");
231 spdk_json_write_string(w
, trid
->trsvcid
);
232 spdk_json_write_object_end(w
);
234 spdk_json_write_array_end(w
);
236 spdk_json_write_name(w
, "allow_any_host");
237 spdk_json_write_bool(w
, spdk_nvmf_subsystem_get_allow_any_host(subsystem
));
239 spdk_json_write_name(w
, "hosts");
240 spdk_json_write_array_begin(w
);
242 for (host
= spdk_nvmf_subsystem_get_first_host(subsystem
); host
!= NULL
;
243 host
= spdk_nvmf_subsystem_get_next_host(subsystem
, host
)) {
244 spdk_json_write_object_begin(w
);
245 spdk_json_write_name(w
, "nqn");
246 spdk_json_write_string(w
, spdk_nvmf_host_get_nqn(host
));
247 spdk_json_write_object_end(w
);
249 spdk_json_write_array_end(w
);
251 if (spdk_nvmf_subsystem_get_type(subsystem
) == SPDK_NVMF_SUBTYPE_NVME
) {
252 struct spdk_nvmf_ns
*ns
;
253 struct spdk_nvmf_ns_opts ns_opts
;
254 uint32_t max_namespaces
;
256 spdk_json_write_name(w
, "serial_number");
257 spdk_json_write_string(w
, spdk_nvmf_subsystem_get_sn(subsystem
));
259 max_namespaces
= spdk_nvmf_subsystem_get_max_namespaces(subsystem
);
260 if (max_namespaces
!= 0) {
261 spdk_json_write_named_uint32(w
, "max_namespaces", max_namespaces
);
264 spdk_json_write_name(w
, "namespaces");
265 spdk_json_write_array_begin(w
);
266 for (ns
= spdk_nvmf_subsystem_get_first_ns(subsystem
); ns
!= NULL
;
267 ns
= spdk_nvmf_subsystem_get_next_ns(subsystem
, ns
)) {
268 spdk_nvmf_ns_get_opts(ns
, &ns_opts
, sizeof(ns_opts
));
269 spdk_json_write_object_begin(w
);
270 spdk_json_write_name(w
, "nsid");
271 spdk_json_write_int32(w
, spdk_nvmf_ns_get_id(ns
));
272 spdk_json_write_name(w
, "bdev_name");
273 spdk_json_write_string(w
, spdk_bdev_get_name(spdk_nvmf_ns_get_bdev(ns
)));
274 /* NOTE: "name" is kept for compatibility only - new code should use bdev_name. */
275 spdk_json_write_name(w
, "name");
276 spdk_json_write_string(w
, spdk_bdev_get_name(spdk_nvmf_ns_get_bdev(ns
)));
278 if (!spdk_mem_all_zero(ns_opts
.nguid
, sizeof(ns_opts
.nguid
))) {
279 spdk_json_write_name(w
, "nguid");
280 json_write_hex_str(w
, ns_opts
.nguid
, sizeof(ns_opts
.nguid
));
283 if (!spdk_mem_all_zero(ns_opts
.eui64
, sizeof(ns_opts
.eui64
))) {
284 spdk_json_write_name(w
, "eui64");
285 json_write_hex_str(w
, ns_opts
.eui64
, sizeof(ns_opts
.eui64
));
288 if (!spdk_mem_all_zero(&ns_opts
.uuid
, sizeof(ns_opts
.uuid
))) {
289 char uuid_str
[SPDK_UUID_STRING_LEN
];
291 spdk_uuid_fmt_lower(uuid_str
, sizeof(uuid_str
), &ns_opts
.uuid
);
292 spdk_json_write_name(w
, "uuid");
293 spdk_json_write_string(w
, uuid_str
);
296 spdk_json_write_object_end(w
);
298 spdk_json_write_array_end(w
);
300 spdk_json_write_object_end(w
);
304 spdk_rpc_get_nvmf_subsystems(struct spdk_jsonrpc_request
*request
,
305 const struct spdk_json_val
*params
)
307 struct spdk_json_write_ctx
*w
;
308 struct spdk_nvmf_subsystem
*subsystem
;
310 if (params
!= NULL
) {
311 spdk_jsonrpc_send_error_response(request
, SPDK_JSONRPC_ERROR_INVALID_PARAMS
,
312 "get_nvmf_subsystems requires no parameters");
316 w
= spdk_jsonrpc_begin_result(request
);
321 spdk_json_write_array_begin(w
);
322 subsystem
= spdk_nvmf_subsystem_get_first(g_spdk_nvmf_tgt
);
324 dump_nvmf_subsystem(w
, subsystem
);
325 subsystem
= spdk_nvmf_subsystem_get_next(subsystem
);
327 spdk_json_write_array_end(w
);
328 spdk_jsonrpc_end_result(request
, w
);
330 SPDK_RPC_REGISTER("get_nvmf_subsystems", spdk_rpc_get_nvmf_subsystems
, SPDK_RPC_RUNTIME
)
332 struct rpc_subsystem_create
{
335 uint32_t max_namespaces
;
339 static const struct spdk_json_object_decoder rpc_subsystem_create_decoders
[] = {
340 {"nqn", offsetof(struct rpc_subsystem_create
, nqn
), spdk_json_decode_string
},
341 {"serial_number", offsetof(struct rpc_subsystem_create
, serial_number
), spdk_json_decode_string
, true},
342 {"max_namespaces", offsetof(struct rpc_subsystem_create
, max_namespaces
), spdk_json_decode_uint32
, true},
343 {"allow_any_host", offsetof(struct rpc_subsystem_create
, allow_any_host
), spdk_json_decode_bool
, true},
347 spdk_rpc_nvmf_subsystem_started(struct spdk_nvmf_subsystem
*subsystem
,
348 void *cb_arg
, int status
)
350 struct spdk_jsonrpc_request
*request
= cb_arg
;
351 struct spdk_json_write_ctx
*w
;
353 w
= spdk_jsonrpc_begin_result(request
);
358 spdk_json_write_bool(w
, true);
359 spdk_jsonrpc_end_result(request
, w
);
363 spdk_rpc_nvmf_subsystem_create(struct spdk_jsonrpc_request
*request
,
364 const struct spdk_json_val
*params
)
366 struct rpc_subsystem_create
*req
;
367 struct spdk_nvmf_subsystem
*subsystem
;
369 req
= calloc(1, sizeof(*req
));
374 if (spdk_json_decode_object(params
, rpc_subsystem_create_decoders
,
375 SPDK_COUNTOF(rpc_subsystem_create_decoders
),
377 SPDK_ERRLOG("spdk_json_decode_object failed\n");
381 subsystem
= spdk_nvmf_subsystem_create(g_spdk_nvmf_tgt
, req
->nqn
, SPDK_NVMF_SUBTYPE_NVME
,
382 req
->max_namespaces
);
387 if (req
->serial_number
) {
388 if (spdk_nvmf_subsystem_set_sn(subsystem
, req
->serial_number
)) {
389 SPDK_ERRLOG("Subsystem %s: invalid serial number '%s'\n", req
->nqn
, req
->serial_number
);
394 spdk_nvmf_subsystem_set_allow_any_host(subsystem
, req
->allow_any_host
);
397 free(req
->serial_number
);
400 spdk_nvmf_subsystem_start(subsystem
,
401 spdk_rpc_nvmf_subsystem_started
,
407 spdk_jsonrpc_send_error_response(request
, SPDK_JSONRPC_ERROR_INVALID_PARAMS
, "Invalid parameters");
410 free(req
->serial_number
);
414 SPDK_RPC_REGISTER("nvmf_subsystem_create", spdk_rpc_nvmf_subsystem_create
, SPDK_RPC_RUNTIME
)
416 struct rpc_delete_subsystem
{
421 free_rpc_delete_subsystem(struct rpc_delete_subsystem
*r
)
427 spdk_rpc_nvmf_subsystem_stopped(struct spdk_nvmf_subsystem
*subsystem
,
428 void *cb_arg
, int status
)
430 struct spdk_jsonrpc_request
*request
= cb_arg
;
431 struct spdk_json_write_ctx
*w
;
433 spdk_nvmf_subsystem_destroy(subsystem
);
435 w
= spdk_jsonrpc_begin_result(request
);
440 spdk_json_write_bool(w
, true);
441 spdk_jsonrpc_end_result(request
, w
);
444 static const struct spdk_json_object_decoder rpc_delete_subsystem_decoders
[] = {
445 {"nqn", offsetof(struct rpc_delete_subsystem
, nqn
), spdk_json_decode_string
},
449 spdk_rpc_delete_nvmf_subsystem(struct spdk_jsonrpc_request
*request
,
450 const struct spdk_json_val
*params
)
452 struct rpc_delete_subsystem req
= {};
453 struct spdk_nvmf_subsystem
*subsystem
;
455 if (spdk_json_decode_object(params
, rpc_delete_subsystem_decoders
,
456 SPDK_COUNTOF(rpc_delete_subsystem_decoders
),
458 SPDK_ERRLOG("spdk_json_decode_object failed\n");
462 if (req
.nqn
== NULL
) {
463 SPDK_ERRLOG("missing name param\n");
467 subsystem
= spdk_nvmf_tgt_find_subsystem(g_spdk_nvmf_tgt
, req
.nqn
);
472 free_rpc_delete_subsystem(&req
);
474 spdk_nvmf_subsystem_stop(subsystem
,
475 spdk_rpc_nvmf_subsystem_stopped
,
481 spdk_jsonrpc_send_error_response(request
, SPDK_JSONRPC_ERROR_INVALID_PARAMS
, "Invalid parameters");
482 free_rpc_delete_subsystem(&req
);
484 SPDK_RPC_REGISTER("delete_nvmf_subsystem", spdk_rpc_delete_nvmf_subsystem
, SPDK_RPC_RUNTIME
)
486 struct rpc_listen_address
{
493 #define RPC_MAX_LISTEN_ADDRESSES 255
494 #define RPC_MAX_NAMESPACES 255
496 struct rpc_listen_addresses
{
497 size_t num_listen_address
;
498 struct rpc_listen_address addresses
[RPC_MAX_LISTEN_ADDRESSES
];
501 static const struct spdk_json_object_decoder rpc_listen_address_decoders
[] = {
502 /* NOTE: "transport" is kept for compatibility; new code should use "trtype" */
503 {"transport", offsetof(struct rpc_listen_address
, transport
), spdk_json_decode_string
, true},
504 {"trtype", offsetof(struct rpc_listen_address
, transport
), spdk_json_decode_string
, true},
505 {"adrfam", offsetof(struct rpc_listen_address
, adrfam
), spdk_json_decode_string
, true},
506 {"traddr", offsetof(struct rpc_listen_address
, traddr
), spdk_json_decode_string
},
507 {"trsvcid", offsetof(struct rpc_listen_address
, trsvcid
), spdk_json_decode_string
},
511 decode_rpc_listen_address(const struct spdk_json_val
*val
, void *out
)
513 struct rpc_listen_address
*req
= (struct rpc_listen_address
*)out
;
514 if (spdk_json_decode_object(val
, rpc_listen_address_decoders
,
515 SPDK_COUNTOF(rpc_listen_address_decoders
),
517 SPDK_ERRLOG("spdk_json_decode_object failed\n");
524 free_rpc_listen_address(struct rpc_listen_address
*r
)
532 enum nvmf_rpc_listen_op
{
534 NVMF_RPC_LISTEN_REMOVE
,
537 struct nvmf_rpc_listener_ctx
{
539 struct spdk_nvmf_subsystem
*subsystem
;
540 struct rpc_listen_address address
;
542 struct spdk_jsonrpc_request
*request
;
543 struct spdk_nvme_transport_id trid
;
544 enum nvmf_rpc_listen_op op
;
548 static const struct spdk_json_object_decoder nvmf_rpc_listener_decoder
[] = {
549 {"nqn", offsetof(struct nvmf_rpc_listener_ctx
, nqn
), spdk_json_decode_string
},
550 {"listen_address", offsetof(struct nvmf_rpc_listener_ctx
, address
), decode_rpc_listen_address
},
554 nvmf_rpc_listener_ctx_free(struct nvmf_rpc_listener_ctx
*ctx
)
557 free_rpc_listen_address(&ctx
->address
);
562 nvmf_rpc_listen_resumed(struct spdk_nvmf_subsystem
*subsystem
,
563 void *cb_arg
, int status
)
565 struct nvmf_rpc_listener_ctx
*ctx
= cb_arg
;
566 struct spdk_jsonrpc_request
*request
;
567 struct spdk_json_write_ctx
*w
;
569 request
= ctx
->request
;
570 if (ctx
->response_sent
) {
571 /* If an error occurred, the response has already been sent. */
572 nvmf_rpc_listener_ctx_free(ctx
);
576 nvmf_rpc_listener_ctx_free(ctx
);
578 w
= spdk_jsonrpc_begin_result(request
);
583 spdk_json_write_bool(w
, true);
584 spdk_jsonrpc_end_result(request
, w
);
588 nvmf_rpc_tgt_listen(void *cb_arg
, int status
)
590 struct nvmf_rpc_listener_ctx
*ctx
= cb_arg
;
593 spdk_jsonrpc_send_error_response(ctx
->request
, SPDK_JSONRPC_ERROR_INVALID_PARAMS
,
594 "Invalid parameters");
595 ctx
->response_sent
= true;
597 if (spdk_nvmf_subsystem_add_listener(ctx
->subsystem
, &ctx
->trid
)) {
598 spdk_jsonrpc_send_error_response(ctx
->request
, SPDK_JSONRPC_ERROR_INVALID_PARAMS
,
599 "Invalid parameters");
600 ctx
->response_sent
= true;
604 if (spdk_nvmf_subsystem_resume(ctx
->subsystem
, nvmf_rpc_listen_resumed
, ctx
)) {
605 if (!ctx
->response_sent
) {
606 spdk_jsonrpc_send_error_response(ctx
->request
, SPDK_JSONRPC_ERROR_INTERNAL_ERROR
, "Internal error");
608 nvmf_rpc_listener_ctx_free(ctx
);
609 /* Can't really do anything to recover here - subsystem will remain paused. */
614 nvmf_rpc_listen_paused(struct spdk_nvmf_subsystem
*subsystem
,
615 void *cb_arg
, int status
)
617 struct nvmf_rpc_listener_ctx
*ctx
= cb_arg
;
619 if (ctx
->op
== NVMF_RPC_LISTEN_ADD
) {
620 spdk_nvmf_tgt_listen(g_spdk_nvmf_tgt
, &ctx
->trid
, nvmf_rpc_tgt_listen
, ctx
);
622 } else if (ctx
->op
== NVMF_RPC_LISTEN_REMOVE
) {
623 if (spdk_nvmf_subsystem_remove_listener(subsystem
, &ctx
->trid
)) {
624 SPDK_ERRLOG("Unable to remove listener.\n");
625 spdk_jsonrpc_send_error_response(ctx
->request
, SPDK_JSONRPC_ERROR_INVALID_PARAMS
,
626 "Invalid parameters");
627 ctx
->response_sent
= true;
630 spdk_jsonrpc_send_error_response(ctx
->request
, SPDK_JSONRPC_ERROR_INVALID_PARAMS
,
631 "Invalid parameters");
632 ctx
->response_sent
= true;
635 if (spdk_nvmf_subsystem_resume(subsystem
, nvmf_rpc_listen_resumed
, ctx
)) {
636 if (!ctx
->response_sent
) {
637 spdk_jsonrpc_send_error_response(ctx
->request
, SPDK_JSONRPC_ERROR_INTERNAL_ERROR
, "Internal error");
639 nvmf_rpc_listener_ctx_free(ctx
);
640 /* Can't really do anything to recover here - subsystem will remain paused. */
645 rpc_listen_address_to_trid(const struct rpc_listen_address
*address
,
646 struct spdk_nvme_transport_id
*trid
)
650 memset(trid
, 0, sizeof(*trid
));
652 if (spdk_nvme_transport_id_parse_trtype(&trid
->trtype
, address
->transport
)) {
653 SPDK_ERRLOG("Invalid transport type: %s\n", address
->transport
);
657 if (address
->adrfam
) {
658 if (spdk_nvme_transport_id_parse_adrfam(&trid
->adrfam
, address
->adrfam
)) {
659 SPDK_ERRLOG("Invalid adrfam: %s\n", address
->adrfam
);
663 trid
->adrfam
= SPDK_NVMF_ADRFAM_IPV4
;
666 len
= strlen(address
->traddr
);
667 if (len
> sizeof(trid
->traddr
) - 1) {
668 SPDK_ERRLOG("Transport address longer than %zu characters: %s\n",
669 sizeof(trid
->traddr
) - 1, address
->traddr
);
672 memcpy(trid
->traddr
, address
->traddr
, len
+ 1);
674 len
= strlen(address
->trsvcid
);
675 if (len
> sizeof(trid
->trsvcid
) - 1) {
676 SPDK_ERRLOG("Transport service id longer than %zu characters: %s\n",
677 sizeof(trid
->trsvcid
) - 1, address
->trsvcid
);
680 memcpy(trid
->trsvcid
, address
->trsvcid
, len
+ 1);
686 nvmf_rpc_subsystem_add_listener(struct spdk_jsonrpc_request
*request
,
687 const struct spdk_json_val
*params
)
689 struct nvmf_rpc_listener_ctx
*ctx
;
690 struct spdk_nvmf_subsystem
*subsystem
;
692 ctx
= calloc(1, sizeof(*ctx
));
694 spdk_jsonrpc_send_error_response(request
, SPDK_JSONRPC_ERROR_INTERNAL_ERROR
, "Out of memory");
698 ctx
->request
= request
;
700 if (spdk_json_decode_object(params
, nvmf_rpc_listener_decoder
,
701 SPDK_COUNTOF(nvmf_rpc_listener_decoder
),
703 SPDK_ERRLOG("spdk_json_decode_object failed\n");
704 spdk_jsonrpc_send_error_response(request
, SPDK_JSONRPC_ERROR_INVALID_PARAMS
, "Invalid parameters");
705 nvmf_rpc_listener_ctx_free(ctx
);
709 subsystem
= spdk_nvmf_tgt_find_subsystem(g_spdk_nvmf_tgt
, ctx
->nqn
);
711 SPDK_ERRLOG("Unable to find subsystem with NQN %s\n", ctx
->nqn
);
712 spdk_jsonrpc_send_error_response(request
, SPDK_JSONRPC_ERROR_INVALID_PARAMS
, "Invalid parameters");
713 nvmf_rpc_listener_ctx_free(ctx
);
717 ctx
->subsystem
= subsystem
;
719 if (rpc_listen_address_to_trid(&ctx
->address
, &ctx
->trid
)) {
720 spdk_jsonrpc_send_error_response(ctx
->request
, SPDK_JSONRPC_ERROR_INVALID_PARAMS
,
721 "Invalid parameters");
722 nvmf_rpc_listener_ctx_free(ctx
);
726 ctx
->op
= NVMF_RPC_LISTEN_ADD
;
728 if (spdk_nvmf_subsystem_pause(subsystem
, nvmf_rpc_listen_paused
, ctx
)) {
729 spdk_jsonrpc_send_error_response(request
, SPDK_JSONRPC_ERROR_INTERNAL_ERROR
, "Internal error");
730 nvmf_rpc_listener_ctx_free(ctx
);
734 SPDK_RPC_REGISTER("nvmf_subsystem_add_listener", nvmf_rpc_subsystem_add_listener
, SPDK_RPC_RUNTIME
);
737 nvmf_rpc_subsystem_remove_listener(struct spdk_jsonrpc_request
*request
,
738 const struct spdk_json_val
*params
)
740 struct nvmf_rpc_listener_ctx
*ctx
;
741 struct spdk_nvmf_subsystem
*subsystem
;
743 ctx
= calloc(1, sizeof(*ctx
));
745 spdk_jsonrpc_send_error_response(request
, SPDK_JSONRPC_ERROR_INTERNAL_ERROR
, "Out of memory");
749 ctx
->request
= request
;
751 if (spdk_json_decode_object(params
, nvmf_rpc_listener_decoder
,
752 SPDK_COUNTOF(nvmf_rpc_listener_decoder
),
754 SPDK_ERRLOG("spdk_json_decode_object failed\n");
755 spdk_jsonrpc_send_error_response(request
, SPDK_JSONRPC_ERROR_INVALID_PARAMS
, "Invalid parameters");
756 nvmf_rpc_listener_ctx_free(ctx
);
760 subsystem
= spdk_nvmf_tgt_find_subsystem(g_spdk_nvmf_tgt
, ctx
->nqn
);
762 SPDK_ERRLOG("Unable to find subsystem with NQN %s\n", ctx
->nqn
);
763 spdk_jsonrpc_send_error_response(request
, SPDK_JSONRPC_ERROR_INVALID_PARAMS
, "Invalid parameters");
764 nvmf_rpc_listener_ctx_free(ctx
);
768 ctx
->subsystem
= subsystem
;
770 if (rpc_listen_address_to_trid(&ctx
->address
, &ctx
->trid
)) {
771 spdk_jsonrpc_send_error_response(ctx
->request
, SPDK_JSONRPC_ERROR_INVALID_PARAMS
,
772 "Invalid parameters");
773 nvmf_rpc_listener_ctx_free(ctx
);
777 ctx
->op
= NVMF_RPC_LISTEN_REMOVE
;
779 if (spdk_nvmf_subsystem_pause(subsystem
, nvmf_rpc_listen_paused
, ctx
)) {
780 spdk_jsonrpc_send_error_response(request
, SPDK_JSONRPC_ERROR_INTERNAL_ERROR
, "Internal error");
781 nvmf_rpc_listener_ctx_free(ctx
);
786 SPDK_RPC_REGISTER("nvmf_subsystem_remove_listener", nvmf_rpc_subsystem_remove_listener
,
789 struct spdk_nvmf_ns_params
{
794 struct spdk_uuid uuid
;
797 struct rpc_namespaces
{
799 struct spdk_nvmf_ns_params ns_params
[RPC_MAX_NAMESPACES
];
803 static const struct spdk_json_object_decoder rpc_ns_params_decoders
[] = {
804 {"nsid", offsetof(struct spdk_nvmf_ns_params
, nsid
), spdk_json_decode_uint32
, true},
805 {"bdev_name", offsetof(struct spdk_nvmf_ns_params
, bdev_name
), spdk_json_decode_string
},
806 {"nguid", offsetof(struct spdk_nvmf_ns_params
, nguid
), decode_ns_nguid
, true},
807 {"eui64", offsetof(struct spdk_nvmf_ns_params
, eui64
), decode_ns_eui64
, true},
808 {"uuid", offsetof(struct spdk_nvmf_ns_params
, uuid
), decode_ns_uuid
, true},
812 decode_rpc_ns_params(const struct spdk_json_val
*val
, void *out
)
814 struct spdk_nvmf_ns_params
*ns_params
= out
;
816 return spdk_json_decode_object(val
, rpc_ns_params_decoders
,
817 SPDK_COUNTOF(rpc_ns_params_decoders
),
821 struct nvmf_rpc_ns_ctx
{
823 struct spdk_nvmf_ns_params ns_params
;
825 struct spdk_jsonrpc_request
*request
;
829 static const struct spdk_json_object_decoder nvmf_rpc_subsystem_ns_decoder
[] = {
830 {"nqn", offsetof(struct nvmf_rpc_ns_ctx
, nqn
), spdk_json_decode_string
},
831 {"namespace", offsetof(struct nvmf_rpc_ns_ctx
, ns_params
), decode_rpc_ns_params
},
835 nvmf_rpc_ns_ctx_free(struct nvmf_rpc_ns_ctx
*ctx
)
838 free(ctx
->ns_params
.bdev_name
);
843 nvmf_rpc_ns_resumed(struct spdk_nvmf_subsystem
*subsystem
,
844 void *cb_arg
, int status
)
846 struct nvmf_rpc_ns_ctx
*ctx
= cb_arg
;
847 struct spdk_jsonrpc_request
*request
= ctx
->request
;
848 uint32_t nsid
= ctx
->ns_params
.nsid
;
849 bool response_sent
= ctx
->response_sent
;
850 struct spdk_json_write_ctx
*w
;
852 nvmf_rpc_ns_ctx_free(ctx
);
858 w
= spdk_jsonrpc_begin_result(request
);
863 spdk_json_write_uint32(w
, nsid
);
864 spdk_jsonrpc_end_result(request
, w
);
868 nvmf_rpc_ns_paused(struct spdk_nvmf_subsystem
*subsystem
,
869 void *cb_arg
, int status
)
871 struct nvmf_rpc_ns_ctx
*ctx
= cb_arg
;
872 struct spdk_nvmf_ns_opts ns_opts
;
873 struct spdk_bdev
*bdev
;
875 bdev
= spdk_bdev_get_by_name(ctx
->ns_params
.bdev_name
);
877 SPDK_ERRLOG("No bdev with name %s\n", ctx
->ns_params
.bdev_name
);
878 spdk_jsonrpc_send_error_response(ctx
->request
, SPDK_JSONRPC_ERROR_INVALID_PARAMS
,
879 "Invalid parameters");
880 ctx
->response_sent
= true;
884 spdk_nvmf_ns_opts_get_defaults(&ns_opts
, sizeof(ns_opts
));
885 ns_opts
.nsid
= ctx
->ns_params
.nsid
;
887 SPDK_STATIC_ASSERT(sizeof(ns_opts
.nguid
) == sizeof(ctx
->ns_params
.nguid
), "size mismatch");
888 memcpy(ns_opts
.nguid
, ctx
->ns_params
.nguid
, sizeof(ns_opts
.nguid
));
890 SPDK_STATIC_ASSERT(sizeof(ns_opts
.eui64
) == sizeof(ctx
->ns_params
.eui64
), "size mismatch");
891 memcpy(ns_opts
.eui64
, ctx
->ns_params
.eui64
, sizeof(ns_opts
.eui64
));
893 if (!spdk_mem_all_zero(&ctx
->ns_params
.uuid
, sizeof(ctx
->ns_params
.uuid
))) {
894 ns_opts
.uuid
= ctx
->ns_params
.uuid
;
897 ctx
->ns_params
.nsid
= spdk_nvmf_subsystem_add_ns(subsystem
, bdev
, &ns_opts
, sizeof(ns_opts
));
898 if (ctx
->ns_params
.nsid
== 0) {
899 SPDK_ERRLOG("Unable to add namespace\n");
900 spdk_jsonrpc_send_error_response(ctx
->request
, SPDK_JSONRPC_ERROR_INVALID_PARAMS
,
901 "Invalid parameters");
902 ctx
->response_sent
= true;
907 if (spdk_nvmf_subsystem_resume(subsystem
, nvmf_rpc_ns_resumed
, ctx
)) {
908 spdk_jsonrpc_send_error_response(ctx
->request
, SPDK_JSONRPC_ERROR_INTERNAL_ERROR
, "Internal error");
909 nvmf_rpc_ns_ctx_free(ctx
);
915 nvmf_rpc_subsystem_add_ns(struct spdk_jsonrpc_request
*request
,
916 const struct spdk_json_val
*params
)
918 struct nvmf_rpc_ns_ctx
*ctx
;
919 struct spdk_nvmf_subsystem
*subsystem
;
921 ctx
= calloc(1, sizeof(*ctx
));
923 spdk_jsonrpc_send_error_response(request
, SPDK_JSONRPC_ERROR_INTERNAL_ERROR
, "Out of memory");
927 if (spdk_json_decode_object(params
, nvmf_rpc_subsystem_ns_decoder
,
928 SPDK_COUNTOF(nvmf_rpc_subsystem_ns_decoder
),
930 SPDK_ERRLOG("spdk_json_decode_object failed\n");
931 spdk_jsonrpc_send_error_response(request
, SPDK_JSONRPC_ERROR_INVALID_PARAMS
, "Invalid parameters");
932 nvmf_rpc_ns_ctx_free(ctx
);
936 ctx
->request
= request
;
937 ctx
->response_sent
= false;
939 subsystem
= spdk_nvmf_tgt_find_subsystem(g_spdk_nvmf_tgt
, ctx
->nqn
);
941 SPDK_ERRLOG("Unable to find subsystem with NQN %s\n", ctx
->nqn
);
942 spdk_jsonrpc_send_error_response(request
, SPDK_JSONRPC_ERROR_INVALID_PARAMS
, "Invalid parameters");
943 nvmf_rpc_ns_ctx_free(ctx
);
947 if (spdk_nvmf_subsystem_pause(subsystem
, nvmf_rpc_ns_paused
, ctx
)) {
948 spdk_jsonrpc_send_error_response(request
, SPDK_JSONRPC_ERROR_INTERNAL_ERROR
, "Internal error");
949 nvmf_rpc_ns_ctx_free(ctx
);
953 SPDK_RPC_REGISTER("nvmf_subsystem_add_ns", nvmf_rpc_subsystem_add_ns
, SPDK_RPC_RUNTIME
)
955 struct nvmf_rpc_remove_ns_ctx
{
959 struct spdk_jsonrpc_request
*request
;
963 static const struct spdk_json_object_decoder nvmf_rpc_subsystem_remove_ns_decoder
[] = {
964 {"nqn", offsetof(struct nvmf_rpc_remove_ns_ctx
, nqn
), spdk_json_decode_string
},
965 {"nsid", offsetof(struct nvmf_rpc_remove_ns_ctx
, nsid
), spdk_json_decode_uint32
},
969 nvmf_rpc_remove_ns_ctx_free(struct nvmf_rpc_remove_ns_ctx
*ctx
)
976 nvmf_rpc_remove_ns_resumed(struct spdk_nvmf_subsystem
*subsystem
,
977 void *cb_arg
, int status
)
979 struct nvmf_rpc_remove_ns_ctx
*ctx
= cb_arg
;
980 struct spdk_jsonrpc_request
*request
= ctx
->request
;
981 bool response_sent
= ctx
->response_sent
;
982 struct spdk_json_write_ctx
*w
;
984 nvmf_rpc_remove_ns_ctx_free(ctx
);
990 w
= spdk_jsonrpc_begin_result(request
);
995 spdk_json_write_bool(w
, true);
996 spdk_jsonrpc_end_result(request
, w
);
1000 nvmf_rpc_remove_ns_remove_done(struct spdk_nvmf_subsystem
*subsystem
, void *cb_arg
, int status
)
1002 struct nvmf_rpc_remove_ns_ctx
*ctx
;
1007 SPDK_ERRLOG("Unable to remove namespace ID %u\n", ctx
->nsid
);
1008 spdk_jsonrpc_send_error_response(ctx
->request
, SPDK_JSONRPC_ERROR_INVALID_PARAMS
,
1009 "Invalid parameters");
1010 ctx
->response_sent
= true;
1013 if (spdk_nvmf_subsystem_resume(subsystem
, nvmf_rpc_remove_ns_resumed
, ctx
)) {
1014 spdk_jsonrpc_send_error_response(ctx
->request
, SPDK_JSONRPC_ERROR_INTERNAL_ERROR
, "Internal error");
1015 nvmf_rpc_remove_ns_ctx_free(ctx
);
1021 nvmf_rpc_remove_ns_paused(struct spdk_nvmf_subsystem
*subsystem
,
1022 void *cb_arg
, int status
)
1024 struct nvmf_rpc_remove_ns_ctx
*ctx
= cb_arg
;
1027 ret
= spdk_nvmf_subsystem_remove_ns(subsystem
, ctx
->nsid
, nvmf_rpc_remove_ns_remove_done
, ctx
);
1029 SPDK_ERRLOG("Unable to remove namespace ID %u\n", ctx
->nsid
);
1030 spdk_jsonrpc_send_error_response(ctx
->request
, SPDK_JSONRPC_ERROR_INVALID_PARAMS
,
1031 "Invalid parameters");
1032 ctx
->response_sent
= true;
1033 spdk_nvmf_subsystem_resume(subsystem
, nvmf_rpc_remove_ns_resumed
, ctx
);
1038 nvmf_rpc_subsystem_remove_ns(struct spdk_jsonrpc_request
*request
,
1039 const struct spdk_json_val
*params
)
1041 struct nvmf_rpc_remove_ns_ctx
*ctx
;
1042 struct spdk_nvmf_subsystem
*subsystem
;
1044 ctx
= calloc(1, sizeof(*ctx
));
1046 spdk_jsonrpc_send_error_response(request
, SPDK_JSONRPC_ERROR_INTERNAL_ERROR
, "Out of memory");
1050 if (spdk_json_decode_object(params
, nvmf_rpc_subsystem_remove_ns_decoder
,
1051 SPDK_COUNTOF(nvmf_rpc_subsystem_remove_ns_decoder
),
1053 SPDK_ERRLOG("spdk_json_decode_object failed\n");
1054 spdk_jsonrpc_send_error_response(request
, SPDK_JSONRPC_ERROR_INVALID_PARAMS
, "Invalid parameters");
1055 nvmf_rpc_remove_ns_ctx_free(ctx
);
1059 ctx
->request
= request
;
1060 ctx
->response_sent
= false;
1062 subsystem
= spdk_nvmf_tgt_find_subsystem(g_spdk_nvmf_tgt
, ctx
->nqn
);
1064 SPDK_ERRLOG("Unable to find subsystem with NQN %s\n", ctx
->nqn
);
1065 spdk_jsonrpc_send_error_response(request
, SPDK_JSONRPC_ERROR_INVALID_PARAMS
, "Invalid parameters");
1066 nvmf_rpc_remove_ns_ctx_free(ctx
);
1070 if (spdk_nvmf_subsystem_pause(subsystem
, nvmf_rpc_remove_ns_paused
, ctx
)) {
1071 spdk_jsonrpc_send_error_response(request
, SPDK_JSONRPC_ERROR_INTERNAL_ERROR
, "Internal error");
1072 nvmf_rpc_remove_ns_ctx_free(ctx
);
1076 SPDK_RPC_REGISTER("nvmf_subsystem_remove_ns", nvmf_rpc_subsystem_remove_ns
, SPDK_RPC_RUNTIME
)
1078 enum nvmf_rpc_host_op
{
1080 NVMF_RPC_HOST_REMOVE
,
1081 NVMF_RPC_HOST_ALLOW_ANY
,
1084 struct nvmf_rpc_host_ctx
{
1085 struct spdk_jsonrpc_request
*request
;
1090 enum nvmf_rpc_host_op op
;
1092 bool allow_any_host
;
1097 static const struct spdk_json_object_decoder nvmf_rpc_subsystem_host_decoder
[] = {
1098 {"nqn", offsetof(struct nvmf_rpc_host_ctx
, nqn
), spdk_json_decode_string
},
1099 {"host", offsetof(struct nvmf_rpc_host_ctx
, host
), spdk_json_decode_string
},
1103 nvmf_rpc_host_ctx_free(struct nvmf_rpc_host_ctx
*ctx
)
1111 nvmf_rpc_host_resumed(struct spdk_nvmf_subsystem
*subsystem
,
1112 void *cb_arg
, int status
)
1114 struct nvmf_rpc_host_ctx
*ctx
= cb_arg
;
1115 struct spdk_jsonrpc_request
*request
;
1116 struct spdk_json_write_ctx
*w
;
1117 bool response_sent
= ctx
->response_sent
;
1119 request
= ctx
->request
;
1120 nvmf_rpc_host_ctx_free(ctx
);
1122 if (response_sent
) {
1126 w
= spdk_jsonrpc_begin_result(request
);
1131 spdk_json_write_bool(w
, true);
1132 spdk_jsonrpc_end_result(request
, w
);
1136 nvmf_rpc_host_paused(struct spdk_nvmf_subsystem
*subsystem
,
1137 void *cb_arg
, int status
)
1139 struct nvmf_rpc_host_ctx
*ctx
= cb_arg
;
1143 case NVMF_RPC_HOST_ADD
:
1144 rc
= spdk_nvmf_subsystem_add_host(subsystem
, ctx
->host
);
1146 case NVMF_RPC_HOST_REMOVE
:
1147 rc
= spdk_nvmf_subsystem_remove_host(subsystem
, ctx
->host
);
1149 case NVMF_RPC_HOST_ALLOW_ANY
:
1150 rc
= spdk_nvmf_subsystem_set_allow_any_host(subsystem
, ctx
->allow_any_host
);
1155 spdk_jsonrpc_send_error_response(ctx
->request
, SPDK_JSONRPC_ERROR_INTERNAL_ERROR
, "Internal error");
1156 ctx
->response_sent
= true;
1159 if (spdk_nvmf_subsystem_resume(subsystem
, nvmf_rpc_host_resumed
, ctx
)) {
1160 if (!ctx
->response_sent
) {
1161 spdk_jsonrpc_send_error_response(ctx
->request
, SPDK_JSONRPC_ERROR_INTERNAL_ERROR
, "Internal error");
1163 nvmf_rpc_host_ctx_free(ctx
);
1169 nvmf_rpc_subsystem_add_host(struct spdk_jsonrpc_request
*request
,
1170 const struct spdk_json_val
*params
)
1172 struct nvmf_rpc_host_ctx
*ctx
;
1173 struct spdk_nvmf_subsystem
*subsystem
;
1175 ctx
= calloc(1, sizeof(*ctx
));
1177 spdk_jsonrpc_send_error_response(request
, SPDK_JSONRPC_ERROR_INTERNAL_ERROR
, "Out of memory");
1181 if (spdk_json_decode_object(params
, nvmf_rpc_subsystem_host_decoder
,
1182 SPDK_COUNTOF(nvmf_rpc_subsystem_host_decoder
),
1184 SPDK_ERRLOG("spdk_json_decode_object failed\n");
1185 spdk_jsonrpc_send_error_response(request
, SPDK_JSONRPC_ERROR_INVALID_PARAMS
, "Invalid parameters");
1186 nvmf_rpc_host_ctx_free(ctx
);
1190 ctx
->request
= request
;
1191 ctx
->op
= NVMF_RPC_HOST_ADD
;
1192 ctx
->response_sent
= false;
1194 subsystem
= spdk_nvmf_tgt_find_subsystem(g_spdk_nvmf_tgt
, ctx
->nqn
);
1196 SPDK_ERRLOG("Unable to find subsystem with NQN %s\n", ctx
->nqn
);
1197 spdk_jsonrpc_send_error_response(request
, SPDK_JSONRPC_ERROR_INVALID_PARAMS
, "Invalid parameters");
1198 nvmf_rpc_host_ctx_free(ctx
);
1202 if (spdk_nvmf_subsystem_pause(subsystem
, nvmf_rpc_host_paused
, ctx
)) {
1203 spdk_jsonrpc_send_error_response(request
, SPDK_JSONRPC_ERROR_INTERNAL_ERROR
, "Internal error");
1204 nvmf_rpc_host_ctx_free(ctx
);
1208 SPDK_RPC_REGISTER("nvmf_subsystem_add_host", nvmf_rpc_subsystem_add_host
, SPDK_RPC_RUNTIME
)
1211 nvmf_rpc_subsystem_remove_host(struct spdk_jsonrpc_request
*request
,
1212 const struct spdk_json_val
*params
)
1214 struct nvmf_rpc_host_ctx
*ctx
;
1215 struct spdk_nvmf_subsystem
*subsystem
;
1217 ctx
= calloc(1, sizeof(*ctx
));
1219 spdk_jsonrpc_send_error_response(request
, SPDK_JSONRPC_ERROR_INTERNAL_ERROR
, "Out of memory");
1223 if (spdk_json_decode_object(params
, nvmf_rpc_subsystem_host_decoder
,
1224 SPDK_COUNTOF(nvmf_rpc_subsystem_host_decoder
),
1226 SPDK_ERRLOG("spdk_json_decode_object failed\n");
1227 spdk_jsonrpc_send_error_response(request
, SPDK_JSONRPC_ERROR_INVALID_PARAMS
, "Invalid parameters");
1228 nvmf_rpc_host_ctx_free(ctx
);
1232 ctx
->request
= request
;
1233 ctx
->op
= NVMF_RPC_HOST_REMOVE
;
1234 ctx
->response_sent
= false;
1236 subsystem
= spdk_nvmf_tgt_find_subsystem(g_spdk_nvmf_tgt
, ctx
->nqn
);
1238 SPDK_ERRLOG("Unable to find subsystem with NQN %s\n", ctx
->nqn
);
1239 spdk_jsonrpc_send_error_response(request
, SPDK_JSONRPC_ERROR_INVALID_PARAMS
, "Invalid parameters");
1240 nvmf_rpc_host_ctx_free(ctx
);
1244 if (spdk_nvmf_subsystem_pause(subsystem
, nvmf_rpc_host_paused
, ctx
)) {
1245 spdk_jsonrpc_send_error_response(request
, SPDK_JSONRPC_ERROR_INTERNAL_ERROR
, "Internal error");
1246 nvmf_rpc_host_ctx_free(ctx
);
1250 SPDK_RPC_REGISTER("nvmf_subsystem_remove_host", nvmf_rpc_subsystem_remove_host
, SPDK_RPC_RUNTIME
)
1253 static const struct spdk_json_object_decoder nvmf_rpc_subsystem_any_host_decoder
[] = {
1254 {"nqn", offsetof(struct nvmf_rpc_host_ctx
, nqn
), spdk_json_decode_string
},
1255 {"allow_any_host", offsetof(struct nvmf_rpc_host_ctx
, allow_any_host
), spdk_json_decode_bool
},
1259 nvmf_rpc_subsystem_allow_any_host(struct spdk_jsonrpc_request
*request
,
1260 const struct spdk_json_val
*params
)
1262 struct nvmf_rpc_host_ctx
*ctx
;
1263 struct spdk_nvmf_subsystem
*subsystem
;
1265 ctx
= calloc(1, sizeof(*ctx
));
1267 spdk_jsonrpc_send_error_response(request
, SPDK_JSONRPC_ERROR_INTERNAL_ERROR
, "Out of memory");
1271 if (spdk_json_decode_object(params
, nvmf_rpc_subsystem_any_host_decoder
,
1272 SPDK_COUNTOF(nvmf_rpc_subsystem_any_host_decoder
),
1274 SPDK_ERRLOG("spdk_json_decode_object failed\n");
1275 spdk_jsonrpc_send_error_response(request
, SPDK_JSONRPC_ERROR_INVALID_PARAMS
, "Invalid parameters");
1276 nvmf_rpc_host_ctx_free(ctx
);
1280 ctx
->request
= request
;
1281 ctx
->op
= NVMF_RPC_HOST_ALLOW_ANY
;
1282 ctx
->response_sent
= false;
1284 subsystem
= spdk_nvmf_tgt_find_subsystem(g_spdk_nvmf_tgt
, ctx
->nqn
);
1286 SPDK_ERRLOG("Unable to find subsystem with NQN %s\n", ctx
->nqn
);
1287 spdk_jsonrpc_send_error_response(request
, SPDK_JSONRPC_ERROR_INVALID_PARAMS
, "Invalid parameters");
1288 nvmf_rpc_host_ctx_free(ctx
);
1292 if (spdk_nvmf_subsystem_pause(subsystem
, nvmf_rpc_host_paused
, ctx
)) {
1293 spdk_jsonrpc_send_error_response(request
, SPDK_JSONRPC_ERROR_INTERNAL_ERROR
, "Internal error");
1294 nvmf_rpc_host_ctx_free(ctx
);
1298 SPDK_RPC_REGISTER("nvmf_subsystem_allow_any_host", nvmf_rpc_subsystem_allow_any_host
,
1301 static const struct spdk_json_object_decoder nvmf_rpc_subsystem_tgt_opts_decoder
[] = {
1302 {"max_queue_depth", offsetof(struct spdk_nvmf_tgt_opts
, max_queue_depth
), spdk_json_decode_uint16
, true},
1303 {"max_qpairs_per_ctrlr", offsetof(struct spdk_nvmf_tgt_opts
, max_qpairs_per_ctrlr
), spdk_json_decode_uint16
, true},
1304 {"in_capsule_data_size", offsetof(struct spdk_nvmf_tgt_opts
, in_capsule_data_size
), spdk_json_decode_uint32
, true},
1305 {"max_io_size", offsetof(struct spdk_nvmf_tgt_opts
, max_io_size
), spdk_json_decode_uint32
, true},
1306 {"max_subsystems", offsetof(struct spdk_nvmf_tgt_opts
, max_subsystems
), spdk_json_decode_uint32
, true},
1307 {"io_unit_size", offsetof(struct spdk_nvmf_tgt_opts
, io_unit_size
), spdk_json_decode_uint32
, true},
1311 nvmf_rpc_subsystem_set_tgt_opts(struct spdk_jsonrpc_request
*request
,
1312 const struct spdk_json_val
*params
)
1314 struct spdk_nvmf_tgt_opts
*opts
;
1315 struct spdk_json_write_ctx
*w
;
1317 if (g_spdk_nvmf_tgt_opts
!= NULL
) {
1318 SPDK_ERRLOG("this RPC must not be called more than once.\n");
1319 spdk_jsonrpc_send_error_response(request
, SPDK_JSONRPC_ERROR_INTERNAL_ERROR
,
1320 "Must not call more than once");
1324 opts
= calloc(1, sizeof(*opts
));
1326 SPDK_ERRLOG("malloc() failed for target options\n");
1327 spdk_jsonrpc_send_error_response(request
, SPDK_JSONRPC_ERROR_INTERNAL_ERROR
,
1332 spdk_nvmf_tgt_opts_init(opts
);
1334 if (params
!= NULL
) {
1335 if (spdk_json_decode_object(params
, nvmf_rpc_subsystem_tgt_opts_decoder
,
1336 SPDK_COUNTOF(nvmf_rpc_subsystem_tgt_opts_decoder
), opts
)) {
1338 SPDK_ERRLOG("spdk_json_decode_object() failed\n");
1339 spdk_jsonrpc_send_error_response(request
, SPDK_JSONRPC_ERROR_INVALID_PARAMS
,
1340 "Invalid parameters");
1345 g_spdk_nvmf_tgt_opts
= opts
;
1347 w
= spdk_jsonrpc_begin_result(request
);
1352 spdk_json_write_bool(w
, true);
1353 spdk_jsonrpc_end_result(request
, w
);
1355 SPDK_RPC_REGISTER("set_nvmf_target_options", nvmf_rpc_subsystem_set_tgt_opts
, SPDK_RPC_STARTUP
)
1357 static int decode_conn_sched(const struct spdk_json_val
*val
, void *out
)
1359 enum spdk_nvmf_connect_sched
*sched
= out
;
1361 if (spdk_json_strequal(val
, "roundrobin") == true) {
1362 *sched
= CONNECT_SCHED_ROUND_ROBIN
;
1363 } else if (spdk_json_strequal(val
, "hostip") == true) {
1364 *sched
= CONNECT_SCHED_HOST_IP
;
1366 SPDK_ERRLOG("Invalid connection scheduling parameter\n");
1373 static const struct spdk_json_object_decoder nvmf_rpc_subsystem_tgt_conf_decoder
[] = {
1374 {"acceptor_poll_rate", offsetof(struct spdk_nvmf_tgt_conf
, acceptor_poll_rate
), spdk_json_decode_uint32
, true},
1375 {"conn_sched", offsetof(struct spdk_nvmf_tgt_conf
, conn_sched
), decode_conn_sched
, true},
1379 nvmf_rpc_subsystem_set_tgt_conf(struct spdk_jsonrpc_request
*request
,
1380 const struct spdk_json_val
*params
)
1382 struct spdk_nvmf_tgt_conf
*conf
;
1383 struct spdk_json_write_ctx
*w
;
1385 if (g_spdk_nvmf_tgt_conf
!= NULL
) {
1386 SPDK_ERRLOG("this RPC must not be called more than once.\n");
1387 spdk_jsonrpc_send_error_response(request
, SPDK_JSONRPC_ERROR_INTERNAL_ERROR
,
1388 "Must not call more than once");
1392 conf
= calloc(1, sizeof(*conf
));
1394 SPDK_ERRLOG("calloc() failed for target config\n");
1395 spdk_jsonrpc_send_error_response(request
, SPDK_JSONRPC_ERROR_INTERNAL_ERROR
,
1400 conf
->acceptor_poll_rate
= ACCEPT_TIMEOUT_US
;
1401 conf
->conn_sched
= DEFAULT_CONN_SCHED
;
1403 if (params
!= NULL
) {
1404 if (spdk_json_decode_object(params
, nvmf_rpc_subsystem_tgt_conf_decoder
,
1405 SPDK_COUNTOF(nvmf_rpc_subsystem_tgt_conf_decoder
), conf
)) {
1407 SPDK_ERRLOG("spdk_json_decode_object() failed\n");
1408 spdk_jsonrpc_send_error_response(request
, SPDK_JSONRPC_ERROR_INVALID_PARAMS
,
1409 "Invalid parameters");
1414 g_spdk_nvmf_tgt_conf
= conf
;
1416 w
= spdk_jsonrpc_begin_result(request
);
1421 spdk_json_write_bool(w
, true);
1422 spdk_jsonrpc_end_result(request
, w
);
1424 SPDK_RPC_REGISTER("set_nvmf_target_config", nvmf_rpc_subsystem_set_tgt_conf
, SPDK_RPC_STARTUP
)
1426 struct nvmf_rpc_create_transport_ctx
{
1428 struct spdk_nvmf_transport_opts opts
;
1429 struct spdk_jsonrpc_request
*request
;
1432 static const struct spdk_json_object_decoder nvmf_rpc_create_transport_decoder
[] = {
1433 { "trtype", offsetof(struct nvmf_rpc_create_transport_ctx
, trtype
), spdk_json_decode_string
},
1435 "max_queue_depth", offsetof(struct nvmf_rpc_create_transport_ctx
, opts
.max_queue_depth
),
1436 spdk_json_decode_uint16
, true
1439 "max_qpairs_per_ctrlr", offsetof(struct nvmf_rpc_create_transport_ctx
, opts
.max_qpairs_per_ctrlr
),
1440 spdk_json_decode_uint16
, true
1443 "in_capsule_data_size", offsetof(struct nvmf_rpc_create_transport_ctx
, opts
.in_capsule_data_size
),
1444 spdk_json_decode_uint32
, true
1447 "max_io_size", offsetof(struct nvmf_rpc_create_transport_ctx
, opts
.max_io_size
),
1448 spdk_json_decode_uint32
, true
1451 "io_unit_size", offsetof(struct nvmf_rpc_create_transport_ctx
, opts
.io_unit_size
),
1452 spdk_json_decode_uint32
, true
1455 "max_aq_depth", offsetof(struct nvmf_rpc_create_transport_ctx
, opts
.max_aq_depth
),
1456 spdk_json_decode_uint32
, true
1461 nvmf_rpc_create_transport_ctx_free(struct nvmf_rpc_create_transport_ctx
*ctx
)
1468 nvmf_rpc_tgt_add_transport_done(void *cb_arg
, int status
)
1470 struct nvmf_rpc_create_transport_ctx
*ctx
= cb_arg
;
1471 struct spdk_jsonrpc_request
*request
;
1472 struct spdk_json_write_ctx
*w
;
1474 request
= ctx
->request
;
1475 nvmf_rpc_create_transport_ctx_free(ctx
);
1478 SPDK_ERRLOG("Failed to add transport to tgt.(%d)\n", status
);
1479 spdk_jsonrpc_send_error_response_fmt(request
, SPDK_JSONRPC_ERROR_INTERNAL_ERROR
,
1480 "Failed to add transport to tgt.(%d)\n",
1485 w
= spdk_jsonrpc_begin_result(request
);
1490 spdk_json_write_bool(w
, true);
1491 spdk_jsonrpc_end_result(request
, w
);
1495 nvmf_rpc_create_transport(struct spdk_jsonrpc_request
*request
,
1496 const struct spdk_json_val
*params
)
1498 struct nvmf_rpc_create_transport_ctx
*ctx
;
1499 enum spdk_nvme_transport_type trtype
;
1500 struct spdk_nvmf_transport
*transport
;
1502 ctx
= calloc(1, sizeof(*ctx
));
1504 spdk_jsonrpc_send_error_response(request
, SPDK_JSONRPC_ERROR_INTERNAL_ERROR
, "Out of memory");
1508 /* Decode parameters the first time to get the transport type */
1509 if (spdk_json_decode_object(params
, nvmf_rpc_create_transport_decoder
,
1510 SPDK_COUNTOF(nvmf_rpc_create_transport_decoder
),
1512 SPDK_ERRLOG("spdk_json_decode_object failed\n");
1513 spdk_jsonrpc_send_error_response(request
, SPDK_JSONRPC_ERROR_INVALID_PARAMS
, "Invalid parameters");
1514 nvmf_rpc_create_transport_ctx_free(ctx
);
1518 if (spdk_nvme_transport_id_parse_trtype(&trtype
, ctx
->trtype
)) {
1519 SPDK_ERRLOG("Invalid transport type '%s'\n", ctx
->trtype
);
1520 spdk_jsonrpc_send_error_response_fmt(request
, SPDK_JSONRPC_ERROR_INVALID_PARAMS
,
1521 "Invalid transport type '%s'\n", ctx
->trtype
);
1522 nvmf_rpc_create_transport_ctx_free(ctx
);
1526 /* Initialize all the transport options (based on transport type) and decode the
1527 * parameters again to update any options passed in rpc create transport call.
1529 spdk_nvmf_transport_opts_init(trtype
, &ctx
->opts
);
1530 if (spdk_json_decode_object(params
, nvmf_rpc_create_transport_decoder
,
1531 SPDK_COUNTOF(nvmf_rpc_create_transport_decoder
),
1533 SPDK_ERRLOG("spdk_json_decode_object failed\n");
1534 spdk_jsonrpc_send_error_response(request
, SPDK_JSONRPC_ERROR_INVALID_PARAMS
, "Invalid parameters");
1535 nvmf_rpc_create_transport_ctx_free(ctx
);
1539 if (spdk_nvmf_tgt_get_transport(g_spdk_nvmf_tgt
, trtype
)) {
1540 SPDK_ERRLOG("Transport type '%s' already exists\n", ctx
->trtype
);
1541 spdk_jsonrpc_send_error_response_fmt(request
, SPDK_JSONRPC_ERROR_INTERNAL_ERROR
,
1542 "Transport type '%s' already exists\n", ctx
->trtype
);
1543 nvmf_rpc_create_transport_ctx_free(ctx
);
1547 transport
= spdk_nvmf_transport_create(trtype
, &ctx
->opts
);
1550 SPDK_ERRLOG("Transport type '%s' create failed\n", ctx
->trtype
);
1551 spdk_jsonrpc_send_error_response_fmt(request
, SPDK_JSONRPC_ERROR_INTERNAL_ERROR
,
1552 "Transport type '%s' create failed\n", ctx
->trtype
);
1553 nvmf_rpc_create_transport_ctx_free(ctx
);
1557 /* add transport to target */
1558 ctx
->request
= request
;
1559 spdk_nvmf_tgt_add_transport(g_spdk_nvmf_tgt
, transport
, nvmf_rpc_tgt_add_transport_done
, ctx
);
1562 SPDK_RPC_REGISTER("nvmf_create_transport", nvmf_rpc_create_transport
, SPDK_RPC_RUNTIME
)