Branch data 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 : 3917325 : rpc_subsystem_poll(void *arg) 20 : : { 21 : 3917325 : spdk_rpc_accept(); 22 : 3917325 : return SPDK_POLLER_BUSY; 23 : : } 24 : : 25 : : static void 26 : 2804 : rpc_opts_copy(struct spdk_rpc_opts *opts, const struct spdk_rpc_opts *opts_src, 27 : : size_t size) 28 : : { 29 [ - + ]: 2804 : assert(opts); 30 [ - + ]: 2804 : assert(opts_src); 31 : : 32 : 2804 : 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 [ + - ]: 2804 : SET_FIELD(log_file); 40 [ + - ]: 2804 : 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 : 2804 : } 48 : : 49 : : static void 50 : 4344 : rpc_opts_get_default(struct spdk_rpc_opts *opts, size_t size) 51 : : { 52 [ - + ]: 4344 : assert(opts); 53 : : 54 : 4344 : 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 [ + - ]: 4344 : SET_FIELD(log_file, NULL); 62 [ + - ]: 4344 : SET_FIELD(log_level, SPDK_LOG_DISABLED); 63 : : 64 : : #undef SET_FIELD 65 : 4344 : } 66 : : 67 : : int 68 : 4529 : spdk_rpc_initialize(const char *listen_addr, const struct spdk_rpc_opts *_opts) 69 : : { 70 : 2154 : struct spdk_rpc_opts opts; 71 : : int rc; 72 : : 73 [ + + ]: 4529 : if (listen_addr == NULL) { 74 : : /* Not treated as an error */ 75 : 138 : return 0; 76 : : } 77 : : 78 [ - + ]: 4391 : if (!spdk_rpc_verify_methods()) { 79 : 0 : return -EINVAL; 80 : : } 81 : : 82 [ + + - + ]: 4391 : 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 : 4391 : rc = spdk_rpc_listen(listen_addr); 89 [ + + ]: 4391 : if (rc != 0) { 90 : 47 : 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 : 47 : return 0; 94 : : } 95 : : 96 : 4344 : rpc_opts_get_default(&opts, sizeof(opts)); 97 [ + + ]: 4344 : if (_opts != NULL) { 98 : 2804 : rpc_opts_copy(&opts, _opts, _opts->size); 99 : : } 100 : : 101 : 4344 : spdk_jsonrpc_set_log_file(opts.log_file); 102 : 4344 : spdk_jsonrpc_set_log_level(opts.log_level); 103 : : 104 : : /* Register a poller to periodically check for RPCs */ 105 : 4344 : g_rpc_poller = SPDK_POLLER_REGISTER(rpc_subsystem_poll, NULL, RPC_SELECT_INTERVAL); 106 : : 107 : 4344 : return 0; 108 : : } 109 : : 110 : : void 111 : 4639 : spdk_rpc_finish(void) 112 : : { 113 : 4639 : spdk_rpc_close(); 114 : 4639 : spdk_poller_unregister(&g_rpc_poller); 115 : 4639 : }