Line data Source code
1 : /* SPDX-License-Identifier: BSD-3-Clause 2 : * Copyright (C) 2017 Intel Corporation. All rights reserved. 3 : * Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 4 : */ 5 : 6 : #include "spdk/stdinc.h" 7 : 8 : #include "spdk/env.h" 9 : #include "spdk/init.h" 10 : #include "spdk/thread.h" 11 : #include "spdk/log.h" 12 : #include "spdk/rpc.h" 13 : 14 : #define RPC_SELECT_INTERVAL 4000 /* 4ms */ 15 : 16 : static struct spdk_poller *g_rpc_poller = NULL; 17 : 18 : static int 19 0 : rpc_subsystem_poll(void *arg) 20 : { 21 0 : spdk_rpc_accept(); 22 0 : return SPDK_POLLER_BUSY; 23 : } 24 : 25 : static void 26 0 : rpc_opts_copy(struct spdk_rpc_opts *opts, const struct spdk_rpc_opts *opts_src, 27 : size_t size) 28 : { 29 0 : assert(opts); 30 0 : assert(opts_src); 31 : 32 0 : opts->size = size; 33 : 34 : #define SET_FIELD(field) \ 35 : if (offsetof(struct spdk_rpc_opts, field) + sizeof(opts->field) <= size) { \ 36 : opts->field = opts_src->field; \ 37 : } \ 38 : 39 0 : SET_FIELD(log_file); 40 0 : SET_FIELD(log_level); 41 : 42 : /* Do not remove this statement, you should always update this statement when you adding a new field, 43 : * and do not forget to add the SET_FIELD statement for your added field. */ 44 : SPDK_STATIC_ASSERT(sizeof(struct spdk_rpc_opts) == 24, "Incorrect size"); 45 : 46 : #undef SET_FIELD 47 0 : } 48 : 49 : static void 50 0 : rpc_opts_get_default(struct spdk_rpc_opts *opts, size_t size) 51 : { 52 0 : assert(opts); 53 : 54 0 : opts->size = size; 55 : 56 : #define SET_FIELD(field, value) \ 57 : if (offsetof(struct spdk_rpc_opts, field) + sizeof(opts->field) <= size) { \ 58 : opts->field = value; \ 59 : } \ 60 : 61 0 : SET_FIELD(log_file, NULL); 62 0 : SET_FIELD(log_level, SPDK_LOG_DISABLED); 63 : 64 : #undef SET_FIELD 65 0 : } 66 : 67 : int 68 0 : spdk_rpc_initialize(const char *listen_addr, const struct spdk_rpc_opts *_opts) 69 : { 70 0 : struct spdk_rpc_opts opts; 71 : int rc; 72 : 73 0 : if (listen_addr == NULL) { 74 : /* Not treated as an error */ 75 0 : return 0; 76 : } 77 : 78 0 : if (!spdk_rpc_verify_methods()) { 79 0 : return -EINVAL; 80 : } 81 : 82 0 : if (_opts != NULL && _opts->size == 0) { 83 0 : SPDK_ERRLOG("size in the options structure should not be zero\n"); 84 0 : return -EINVAL; 85 : } 86 : 87 : /* Listen on the requested address */ 88 0 : rc = spdk_rpc_listen(listen_addr); 89 0 : if (rc != 0) { 90 0 : SPDK_ERRLOG("Unable to start RPC service at %s\n", listen_addr); 91 : /* TODO: Eventually, treat this as an error. But it historically has not 92 : * been and many tests rely on this gracefully failing. */ 93 0 : return 0; 94 : } 95 : 96 0 : rpc_opts_get_default(&opts, sizeof(opts)); 97 0 : if (_opts != NULL) { 98 0 : rpc_opts_copy(&opts, _opts, _opts->size); 99 : } 100 : 101 0 : spdk_jsonrpc_set_log_file(opts.log_file); 102 0 : spdk_jsonrpc_set_log_level(opts.log_level); 103 : 104 : /* Register a poller to periodically check for RPCs */ 105 0 : g_rpc_poller = SPDK_POLLER_REGISTER(rpc_subsystem_poll, NULL, RPC_SELECT_INTERVAL); 106 : 107 0 : return 0; 108 : } 109 : 110 : void 111 0 : spdk_rpc_finish(void) 112 : { 113 0 : spdk_rpc_close(); 114 0 : spdk_poller_unregister(&g_rpc_poller); 115 0 : }