numam-spdk/lib/iscsi/iscsi_rpc.c
Ben Walker 39e850d17b iscsi: Remove cpumask from portals
Connections will soon be assigned to poll groups, which will be
dynamically moved between CPU cores based on load. It no longer makes
sense to restrict certain portal groups to specific cpu cores in this
model.

Change-Id: Iee983d75febc9797aa60021c5bc0680335e895cd
Signed-off-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/463358
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: Changpeng Liu <changpeng.liu@intel.com>
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
2019-08-08 05:35:01 +00:00

1481 lines
42 KiB
C

/*-
* BSD LICENSE
*
* Copyright (C) 2008-2012 Daisuke Aoyama <aoyama@peach.ne.jp>.
* Copyright (c) Intel Corporation.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Intel Corporation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "iscsi/iscsi.h"
#include "iscsi/conn.h"
#include "iscsi/tgt_node.h"
#include "iscsi/portal_grp.h"
#include "iscsi/init_grp.h"
#include "spdk/rpc.h"
#include "spdk/util.h"
#include "spdk/event.h"
#include "spdk/string.h"
#include "spdk_internal/log.h"
static void
spdk_rpc_get_initiator_groups(struct spdk_jsonrpc_request *request,
const struct spdk_json_val *params)
{
struct spdk_json_write_ctx *w;
if (params != NULL) {
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
"get_initiator_groups requires no parameters");
return;
}
w = spdk_jsonrpc_begin_result(request);
spdk_json_write_array_begin(w);
spdk_iscsi_init_grps_info_json(w);
spdk_json_write_array_end(w);
spdk_jsonrpc_end_result(request, w);
}
SPDK_RPC_REGISTER("get_initiator_groups", spdk_rpc_get_initiator_groups, SPDK_RPC_RUNTIME)
struct rpc_initiator_list {
size_t num_initiators;
char *initiators[MAX_INITIATOR];
};
static int
decode_rpc_initiator_list(const struct spdk_json_val *val, void *out)
{
struct rpc_initiator_list *list = out;
return spdk_json_decode_array(val, spdk_json_decode_string, list->initiators, MAX_INITIATOR,
&list->num_initiators, sizeof(char *));
}
static void
free_rpc_initiator_list(struct rpc_initiator_list *list)
{
size_t i;
for (i = 0; i < list->num_initiators; i++) {
free(list->initiators[i]);
}
}
struct rpc_netmask_list {
size_t num_netmasks;
char *netmasks[MAX_NETMASK];
};
static int
decode_rpc_netmask_list(const struct spdk_json_val *val, void *out)
{
struct rpc_netmask_list *list = out;
return spdk_json_decode_array(val, spdk_json_decode_string, list->netmasks, MAX_NETMASK,
&list->num_netmasks, sizeof(char *));
}
static void
free_rpc_netmask_list(struct rpc_netmask_list *list)
{
size_t i;
for (i = 0; i < list->num_netmasks; i++) {
free(list->netmasks[i]);
}
}
struct rpc_initiator_group {
int32_t tag;
struct rpc_initiator_list initiator_list;
struct rpc_netmask_list netmask_list;
};
static void
free_rpc_initiator_group(struct rpc_initiator_group *ig)
{
free_rpc_initiator_list(&ig->initiator_list);
free_rpc_netmask_list(&ig->netmask_list);
}
static const struct spdk_json_object_decoder rpc_initiator_group_decoders[] = {
{"tag", offsetof(struct rpc_initiator_group, tag), spdk_json_decode_int32},
{"initiators", offsetof(struct rpc_initiator_group, initiator_list), decode_rpc_initiator_list},
{"netmasks", offsetof(struct rpc_initiator_group, netmask_list), decode_rpc_netmask_list},
};
static void
spdk_rpc_add_initiator_group(struct spdk_jsonrpc_request *request,
const struct spdk_json_val *params)
{
struct rpc_initiator_group req = {};
struct spdk_json_write_ctx *w;
if (spdk_json_decode_object(params, rpc_initiator_group_decoders,
SPDK_COUNTOF(rpc_initiator_group_decoders), &req)) {
SPDK_ERRLOG("spdk_json_decode_object failed\n");
goto invalid;
}
if (req.initiator_list.num_initiators == 0 ||
req.netmask_list.num_netmasks == 0) {
goto invalid;
}
if (spdk_iscsi_init_grp_create_from_initiator_list(req.tag,
req.initiator_list.num_initiators,
req.initiator_list.initiators,
req.netmask_list.num_netmasks,
req.netmask_list.netmasks)) {
SPDK_ERRLOG("create_from_initiator_list failed\n");
goto invalid;
}
free_rpc_initiator_group(&req);
w = spdk_jsonrpc_begin_result(request);
spdk_json_write_bool(w, true);
spdk_jsonrpc_end_result(request, w);
return;
invalid:
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
free_rpc_initiator_group(&req);
}
SPDK_RPC_REGISTER("add_initiator_group", spdk_rpc_add_initiator_group, SPDK_RPC_RUNTIME)
static const struct spdk_json_object_decoder rpc_add_or_delete_initiators_decoders[] = {
{"tag", offsetof(struct rpc_initiator_group, tag), spdk_json_decode_int32},
{"initiators", offsetof(struct rpc_initiator_group, initiator_list), decode_rpc_initiator_list, true},
{"netmasks", offsetof(struct rpc_initiator_group, netmask_list), decode_rpc_netmask_list, true},
};
static void
spdk_rpc_add_initiators_to_initiator_group(struct spdk_jsonrpc_request *request,
const struct spdk_json_val *params)
{
struct rpc_initiator_group req = {};
struct spdk_json_write_ctx *w;
if (spdk_json_decode_object(params, rpc_add_or_delete_initiators_decoders,
SPDK_COUNTOF(rpc_add_or_delete_initiators_decoders), &req)) {
SPDK_ERRLOG("spdk_json_decode_object failed\n");
goto invalid;
}
if (spdk_iscsi_init_grp_add_initiators_from_initiator_list(req.tag,
req.initiator_list.num_initiators,
req.initiator_list.initiators,
req.netmask_list.num_netmasks,
req.netmask_list.netmasks)) {
SPDK_ERRLOG("add_initiators_from_initiator_list failed\n");
goto invalid;
}
free_rpc_initiator_group(&req);
w = spdk_jsonrpc_begin_result(request);
spdk_json_write_bool(w, true);
spdk_jsonrpc_end_result(request, w);
return;
invalid:
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
free_rpc_initiator_group(&req);
}
SPDK_RPC_REGISTER("add_initiators_to_initiator_group",
spdk_rpc_add_initiators_to_initiator_group, SPDK_RPC_RUNTIME)
static void
spdk_rpc_delete_initiators_from_initiator_group(struct spdk_jsonrpc_request *request,
const struct spdk_json_val *params)
{
struct rpc_initiator_group req = {};
struct spdk_json_write_ctx *w;
if (spdk_json_decode_object(params, rpc_add_or_delete_initiators_decoders,
SPDK_COUNTOF(rpc_add_or_delete_initiators_decoders), &req)) {
SPDK_ERRLOG("spdk_json_decode_object failed\n");
goto invalid;
}
if (spdk_iscsi_init_grp_delete_initiators_from_initiator_list(req.tag,
req.initiator_list.num_initiators,
req.initiator_list.initiators,
req.netmask_list.num_netmasks,
req.netmask_list.netmasks)) {
SPDK_ERRLOG("delete_initiators_from_initiator_list failed\n");
goto invalid;
}
free_rpc_initiator_group(&req);
w = spdk_jsonrpc_begin_result(request);
spdk_json_write_bool(w, true);
spdk_jsonrpc_end_result(request, w);
return;
invalid:
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
free_rpc_initiator_group(&req);
}
SPDK_RPC_REGISTER("delete_initiators_from_initiator_group",
spdk_rpc_delete_initiators_from_initiator_group, SPDK_RPC_RUNTIME)
struct rpc_delete_initiator_group {
int32_t tag;
};
static const struct spdk_json_object_decoder rpc_delete_initiator_group_decoders[] = {
{"tag", offsetof(struct rpc_delete_initiator_group, tag), spdk_json_decode_int32},
};
static void
spdk_rpc_delete_initiator_group(struct spdk_jsonrpc_request *request,
const struct spdk_json_val *params)
{
struct rpc_delete_initiator_group req = {};
struct spdk_json_write_ctx *w;
struct spdk_iscsi_init_grp *ig;
if (spdk_json_decode_object(params, rpc_delete_initiator_group_decoders,
SPDK_COUNTOF(rpc_delete_initiator_group_decoders),
&req)) {
SPDK_ERRLOG("spdk_json_decode_object failed\n");
goto invalid;
}
ig = spdk_iscsi_init_grp_unregister(req.tag);
if (!ig) {
goto invalid;
}
spdk_iscsi_tgt_node_delete_map(NULL, ig);
spdk_iscsi_init_grp_destroy(ig);
w = spdk_jsonrpc_begin_result(request);
spdk_json_write_bool(w, true);
spdk_jsonrpc_end_result(request, w);
return;
invalid:
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
}
SPDK_RPC_REGISTER("delete_initiator_group", spdk_rpc_delete_initiator_group, SPDK_RPC_RUNTIME)
static void
spdk_rpc_get_target_nodes(struct spdk_jsonrpc_request *request,
const struct spdk_json_val *params)
{
struct spdk_json_write_ctx *w;
if (params != NULL) {
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
"get_target_nodes requires no parameters");
return;
}
w = spdk_jsonrpc_begin_result(request);
spdk_json_write_array_begin(w);
spdk_iscsi_tgt_nodes_info_json(w);
spdk_json_write_array_end(w);
spdk_jsonrpc_end_result(request, w);
}
SPDK_RPC_REGISTER("get_target_nodes", spdk_rpc_get_target_nodes, SPDK_RPC_RUNTIME)
struct rpc_pg_ig_map {
int32_t pg_tag;
int32_t ig_tag;
};
static const struct spdk_json_object_decoder rpc_pg_ig_map_decoders[] = {
{"pg_tag", offsetof(struct rpc_pg_ig_map, pg_tag), spdk_json_decode_int32},
{"ig_tag", offsetof(struct rpc_pg_ig_map, ig_tag), spdk_json_decode_int32},
};
static int
decode_rpc_pg_ig_map(const struct spdk_json_val *val, void *out)
{
struct rpc_pg_ig_map *pg_ig_map = out;
return spdk_json_decode_object(val, rpc_pg_ig_map_decoders,
SPDK_COUNTOF(rpc_pg_ig_map_decoders),
pg_ig_map);
}
struct rpc_pg_ig_maps {
size_t num_maps;
struct rpc_pg_ig_map maps[MAX_TARGET_MAP];
};
static int
decode_rpc_pg_ig_maps(const struct spdk_json_val *val, void *out)
{
struct rpc_pg_ig_maps *pg_ig_maps = out;
return spdk_json_decode_array(val, decode_rpc_pg_ig_map, pg_ig_maps->maps,
MAX_TARGET_MAP, &pg_ig_maps->num_maps,
sizeof(struct rpc_pg_ig_map));
}
#define RPC_CONSTRUCT_TARGET_NODE_MAX_LUN 64
struct rpc_lun {
char *bdev_name;
int32_t lun_id;
};
static const struct spdk_json_object_decoder rpc_lun_decoders[] = {
{"bdev_name", offsetof(struct rpc_lun, bdev_name), spdk_json_decode_string},
{"lun_id", offsetof(struct rpc_lun, lun_id), spdk_json_decode_int32},
};
static int
decode_rpc_lun(const struct spdk_json_val *val, void *out)
{
struct rpc_lun *lun = out;
return spdk_json_decode_object(val, rpc_lun_decoders,
SPDK_COUNTOF(rpc_lun_decoders), lun);
}
struct rpc_luns {
size_t num_luns;
struct rpc_lun luns[RPC_CONSTRUCT_TARGET_NODE_MAX_LUN];
};
static int
decode_rpc_luns(const struct spdk_json_val *val, void *out)
{
struct rpc_luns *luns = out;
return spdk_json_decode_array(val, decode_rpc_lun, luns->luns,
RPC_CONSTRUCT_TARGET_NODE_MAX_LUN,
&luns->num_luns, sizeof(struct rpc_lun));
}
static void
free_rpc_luns(struct rpc_luns *p)
{
size_t i;
for (i = 0; i < p->num_luns; i++) {
free(p->luns[i].bdev_name);
}
}
struct rpc_target_node {
char *name;
char *alias_name;
struct rpc_pg_ig_maps pg_ig_maps;
struct rpc_luns luns;
int32_t queue_depth;
bool disable_chap;
bool require_chap;
bool mutual_chap;
int32_t chap_group;
bool header_digest;
bool data_digest;
};
static void
free_rpc_target_node(struct rpc_target_node *req)
{
free(req->name);
free(req->alias_name);
free_rpc_luns(&req->luns);
}
static const struct spdk_json_object_decoder rpc_target_node_decoders[] = {
{"name", offsetof(struct rpc_target_node, name), spdk_json_decode_string},
{"alias_name", offsetof(struct rpc_target_node, alias_name), spdk_json_decode_string},
{"pg_ig_maps", offsetof(struct rpc_target_node, pg_ig_maps), decode_rpc_pg_ig_maps},
{"luns", offsetof(struct rpc_target_node, luns), decode_rpc_luns},
{"queue_depth", offsetof(struct rpc_target_node, queue_depth), spdk_json_decode_int32},
{"disable_chap", offsetof(struct rpc_target_node, disable_chap), spdk_json_decode_bool, true},
{"require_chap", offsetof(struct rpc_target_node, require_chap), spdk_json_decode_bool, true},
{"mutual_chap", offsetof(struct rpc_target_node, mutual_chap), spdk_json_decode_bool, true},
{"chap_group", offsetof(struct rpc_target_node, chap_group), spdk_json_decode_int32, true},
{"header_digest", offsetof(struct rpc_target_node, header_digest), spdk_json_decode_bool, true},
{"data_digest", offsetof(struct rpc_target_node, data_digest), spdk_json_decode_bool, true},
};
static void
spdk_rpc_construct_target_node(struct spdk_jsonrpc_request *request,
const struct spdk_json_val *params)
{
struct rpc_target_node req = {};
struct spdk_json_write_ctx *w;
struct spdk_iscsi_tgt_node *target;
int32_t pg_tags[MAX_TARGET_MAP] = {0}, ig_tags[MAX_TARGET_MAP] = {0};
char *bdev_names[RPC_CONSTRUCT_TARGET_NODE_MAX_LUN] = {0};
int32_t lun_ids[RPC_CONSTRUCT_TARGET_NODE_MAX_LUN] = {0};
size_t i;
if (spdk_json_decode_object(params, rpc_target_node_decoders,
SPDK_COUNTOF(rpc_target_node_decoders),
&req)) {
SPDK_ERRLOG("spdk_json_decode_object failed\n");
goto invalid;
}
for (i = 0; i < req.pg_ig_maps.num_maps; i++) {
pg_tags[i] = req.pg_ig_maps.maps[i].pg_tag;
ig_tags[i] = req.pg_ig_maps.maps[i].ig_tag;
}
for (i = 0; i < req.luns.num_luns; i++) {
bdev_names[i] = req.luns.luns[i].bdev_name;
lun_ids[i] = req.luns.luns[i].lun_id;
}
/*
* Use default parameters in a few places:
* index = -1 : automatically pick an index for the new target node
* alias = NULL
*/
target = spdk_iscsi_tgt_node_construct(-1, req.name, req.alias_name,
pg_tags,
ig_tags,
req.pg_ig_maps.num_maps,
(const char **)bdev_names,
lun_ids,
req.luns.num_luns,
req.queue_depth,
req.disable_chap,
req.require_chap,
req.mutual_chap,
req.chap_group,
req.header_digest,
req.data_digest);
if (target == NULL) {
goto invalid;
}
free_rpc_target_node(&req);
w = spdk_jsonrpc_begin_result(request);
spdk_json_write_bool(w, true);
spdk_jsonrpc_end_result(request, w);
return;
invalid:
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
free_rpc_target_node(&req);
}
SPDK_RPC_REGISTER("construct_target_node", spdk_rpc_construct_target_node, SPDK_RPC_RUNTIME)
struct rpc_tgt_node_pg_ig_maps {
char *name;
struct rpc_pg_ig_maps pg_ig_maps;
};
static const struct spdk_json_object_decoder rpc_tgt_node_pg_ig_maps_decoders[] = {
{"name", offsetof(struct rpc_tgt_node_pg_ig_maps, name), spdk_json_decode_string},
{"pg_ig_maps", offsetof(struct rpc_tgt_node_pg_ig_maps, pg_ig_maps), decode_rpc_pg_ig_maps},
};
static void
spdk_rpc_add_pg_ig_maps(struct spdk_jsonrpc_request *request,
const struct spdk_json_val *params)
{
struct rpc_tgt_node_pg_ig_maps req = {};
struct spdk_json_write_ctx *w;
struct spdk_iscsi_tgt_node *target;
int32_t pg_tags[MAX_TARGET_MAP] = {0}, ig_tags[MAX_TARGET_MAP] = {0};
size_t i;
int rc;
if (spdk_json_decode_object(params, rpc_tgt_node_pg_ig_maps_decoders,
SPDK_COUNTOF(rpc_tgt_node_pg_ig_maps_decoders),
&req)) {
SPDK_ERRLOG("spdk_json_decode_object failed\n");
goto invalid;
}
target = spdk_iscsi_find_tgt_node(req.name);
if (target == NULL) {
SPDK_ERRLOG("target is not found\n");
goto invalid;
}
for (i = 0; i < req.pg_ig_maps.num_maps; i++) {
pg_tags[i] = req.pg_ig_maps.maps[i].pg_tag;
ig_tags[i] = req.pg_ig_maps.maps[i].ig_tag;
}
rc = spdk_iscsi_tgt_node_add_pg_ig_maps(target, pg_tags, ig_tags,
req.pg_ig_maps.num_maps);
if (rc < 0) {
SPDK_ERRLOG("add pg-ig maps failed\n");
goto invalid;
}
free(req.name);
w = spdk_jsonrpc_begin_result(request);
spdk_json_write_bool(w, true);
spdk_jsonrpc_end_result(request, w);
return;
invalid:
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
"Invalid parameters");
free(req.name);
}
SPDK_RPC_REGISTER("add_pg_ig_maps", spdk_rpc_add_pg_ig_maps, SPDK_RPC_RUNTIME)
static void
spdk_rpc_delete_pg_ig_maps(struct spdk_jsonrpc_request *request,
const struct spdk_json_val *params)
{
struct rpc_tgt_node_pg_ig_maps req = {};
struct spdk_json_write_ctx *w;
struct spdk_iscsi_tgt_node *target;
int32_t pg_tags[MAX_TARGET_MAP] = {0}, ig_tags[MAX_TARGET_MAP] = {0};
size_t i;
int rc;
if (spdk_json_decode_object(params, rpc_tgt_node_pg_ig_maps_decoders,
SPDK_COUNTOF(rpc_tgt_node_pg_ig_maps_decoders),
&req)) {
SPDK_ERRLOG("spdk_json_decode_object failed\n");
goto invalid;
}
target = spdk_iscsi_find_tgt_node(req.name);
if (target == NULL) {
SPDK_ERRLOG("target is not found\n");
goto invalid;
}
for (i = 0; i < req.pg_ig_maps.num_maps; i++) {
pg_tags[i] = req.pg_ig_maps.maps[i].pg_tag;
ig_tags[i] = req.pg_ig_maps.maps[i].ig_tag;
}
rc = spdk_iscsi_tgt_node_delete_pg_ig_maps(target, pg_tags, ig_tags,
req.pg_ig_maps.num_maps);
if (rc < 0) {
SPDK_ERRLOG("remove pg-ig maps failed\n");
goto invalid;
}
free(req.name);
w = spdk_jsonrpc_begin_result(request);
spdk_json_write_bool(w, true);
spdk_jsonrpc_end_result(request, w);
return;
invalid:
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
"Invalid parameters");
free(req.name);
}
SPDK_RPC_REGISTER("delete_pg_ig_maps", spdk_rpc_delete_pg_ig_maps, SPDK_RPC_RUNTIME)
struct rpc_delete_target_node {
char *name;
};
static void
free_rpc_delete_target_node(struct rpc_delete_target_node *r)
{
free(r->name);
}
static const struct spdk_json_object_decoder rpc_delete_target_node_decoders[] = {
{"name", offsetof(struct rpc_delete_target_node, name), spdk_json_decode_string},
};
struct rpc_delete_target_node_ctx {
struct rpc_delete_target_node req;
struct spdk_jsonrpc_request *request;
};
static void
rpc_delete_target_node_done(void *cb_arg, int rc)
{
struct rpc_delete_target_node_ctx *ctx = cb_arg;
struct spdk_json_write_ctx *w;
free_rpc_delete_target_node(&ctx->req);
w = spdk_jsonrpc_begin_result(ctx->request);
if (w == NULL) {
goto exit;
}
spdk_json_write_bool(w, rc == 0);
spdk_jsonrpc_end_result(ctx->request, w);
exit:
free(ctx);
}
static void
spdk_rpc_delete_target_node(struct spdk_jsonrpc_request *request,
const struct spdk_json_val *params)
{
struct rpc_delete_target_node_ctx *ctx;
ctx = calloc(1, sizeof(*ctx));
if (!ctx) {
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
spdk_strerror(ENOMEM));
return;
}
if (spdk_json_decode_object(params, rpc_delete_target_node_decoders,
SPDK_COUNTOF(rpc_delete_target_node_decoders),
&ctx->req)) {
SPDK_ERRLOG("spdk_json_decode_object failed\n");
goto invalid;
}
if (ctx->req.name == NULL) {
SPDK_ERRLOG("missing name param\n");
goto invalid;
}
ctx->request = request;
spdk_iscsi_shutdown_tgt_node_by_name(ctx->req.name,
rpc_delete_target_node_done, ctx);
return;
invalid:
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
free_rpc_delete_target_node(&ctx->req);
free(ctx);
}
SPDK_RPC_REGISTER("delete_target_node", spdk_rpc_delete_target_node, SPDK_RPC_RUNTIME)
static void
spdk_rpc_get_portal_groups(struct spdk_jsonrpc_request *request,
const struct spdk_json_val *params)
{
struct spdk_json_write_ctx *w;
if (params != NULL) {
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
"get_portal_groups requires no parameters");
return;
}
w = spdk_jsonrpc_begin_result(request);
spdk_json_write_array_begin(w);
spdk_iscsi_portal_grps_info_json(w);
spdk_json_write_array_end(w);
spdk_jsonrpc_end_result(request, w);
}
SPDK_RPC_REGISTER("get_portal_groups", spdk_rpc_get_portal_groups, SPDK_RPC_RUNTIME)
struct rpc_portal {
char *host;
char *port;
char *cpumask;
};
struct rpc_portal_list {
size_t num_portals;
struct rpc_portal portals[MAX_PORTAL];
};
struct rpc_portal_group {
int32_t tag;
struct rpc_portal_list portal_list;
};
static void
free_rpc_portal(struct rpc_portal *portal)
{
free(portal->host);
free(portal->port);
free(portal->cpumask);
}
static void
free_rpc_portal_list(struct rpc_portal_list *pl)
{
size_t i;
for (i = 0; i < pl->num_portals; i++) {
free_rpc_portal(&pl->portals[i]);
}
pl->num_portals = 0;
}
static void
free_rpc_portal_group(struct rpc_portal_group *pg)
{
free_rpc_portal_list(&pg->portal_list);
}
static const struct spdk_json_object_decoder rpc_portal_decoders[] = {
{"host", offsetof(struct rpc_portal, host), spdk_json_decode_string},
{"port", offsetof(struct rpc_portal, port), spdk_json_decode_string},
{"cpumask", offsetof(struct rpc_portal, cpumask), spdk_json_decode_string, true},
};
static int
decode_rpc_portal(const struct spdk_json_val *val, void *out)
{
struct rpc_portal *portal = out;
return spdk_json_decode_object(val, rpc_portal_decoders,
SPDK_COUNTOF(rpc_portal_decoders),
portal);
}
static int
decode_rpc_portal_list(const struct spdk_json_val *val, void *out)
{
struct rpc_portal_list *list = out;
return spdk_json_decode_array(val, decode_rpc_portal, list->portals, MAX_PORTAL, &list->num_portals,
sizeof(struct rpc_portal));
}
static const struct spdk_json_object_decoder rpc_portal_group_decoders[] = {
{"tag", offsetof(struct rpc_portal_group, tag), spdk_json_decode_int32},
{"portals", offsetof(struct rpc_portal_group, portal_list), decode_rpc_portal_list},
};
static void
spdk_rpc_add_portal_group(struct spdk_jsonrpc_request *request,
const struct spdk_json_val *params)
{
struct rpc_portal_group req = {};
struct spdk_iscsi_portal_grp *pg = NULL;
struct spdk_iscsi_portal *portal;
struct spdk_json_write_ctx *w;
size_t i = 0;
int rc = -1;
if (spdk_json_decode_object(params, rpc_portal_group_decoders,
SPDK_COUNTOF(rpc_portal_group_decoders),
&req)) {
SPDK_ERRLOG("spdk_json_decode_object failed\n");
goto out;
}
pg = spdk_iscsi_portal_grp_create(req.tag);
if (pg == NULL) {
SPDK_ERRLOG("portal_grp_create failed\n");
goto out;
}
for (i = 0; i < req.portal_list.num_portals; i++) {
if (req.portal_list.portals[i].cpumask) {
SPDK_WARNLOG("A portal was specified with a CPU mask which is no longer supported.\n");
SPDK_WARNLOG("Ignoring the cpumask.\n");
}
portal = spdk_iscsi_portal_create(req.portal_list.portals[i].host,
req.portal_list.portals[i].port);
if (portal == NULL) {
SPDK_ERRLOG("portal_create failed\n");
goto out;
}
spdk_iscsi_portal_grp_add_portal(pg, portal);
}
rc = spdk_iscsi_portal_grp_open(pg);
if (rc != 0) {
SPDK_ERRLOG("portal_grp_open failed\n");
goto out;
}
rc = spdk_iscsi_portal_grp_register(pg);
if (rc != 0) {
SPDK_ERRLOG("portal_grp_register failed\n");
}
out:
if (rc == 0) {
w = spdk_jsonrpc_begin_result(request);
spdk_json_write_bool(w, true);
spdk_jsonrpc_end_result(request, w);
} else {
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
if (pg != NULL) {
spdk_iscsi_portal_grp_release(pg);
}
}
free_rpc_portal_group(&req);
}
SPDK_RPC_REGISTER("add_portal_group", spdk_rpc_add_portal_group, SPDK_RPC_RUNTIME)
struct rpc_delete_portal_group {
int32_t tag;
};
static const struct spdk_json_object_decoder rpc_delete_portal_group_decoders[] = {
{"tag", offsetof(struct rpc_delete_portal_group, tag), spdk_json_decode_int32},
};
static void
spdk_rpc_delete_portal_group(struct spdk_jsonrpc_request *request,
const struct spdk_json_val *params)
{
struct rpc_delete_portal_group req = {};
struct spdk_json_write_ctx *w;
struct spdk_iscsi_portal_grp *pg;
if (spdk_json_decode_object(params, rpc_delete_portal_group_decoders,
SPDK_COUNTOF(rpc_delete_portal_group_decoders),
&req)) {
SPDK_ERRLOG("spdk_json_decode_object failed\n");
goto invalid;
}
pg = spdk_iscsi_portal_grp_unregister(req.tag);
if (!pg) {
goto invalid;
}
spdk_iscsi_tgt_node_delete_map(pg, NULL);
spdk_iscsi_portal_grp_release(pg);
w = spdk_jsonrpc_begin_result(request);
spdk_json_write_bool(w, true);
spdk_jsonrpc_end_result(request, w);
return;
invalid:
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
}
SPDK_RPC_REGISTER("delete_portal_group", spdk_rpc_delete_portal_group, SPDK_RPC_RUNTIME)
static void
spdk_rpc_get_iscsi_connections(struct spdk_jsonrpc_request *request,
const struct spdk_json_val *params)
{
struct spdk_json_write_ctx *w;
struct spdk_iscsi_conn *conns = g_conns_array;
int i;
uint16_t tsih;
if (params != NULL) {
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
"get_iscsi_connections requires no parameters");
return;
}
w = spdk_jsonrpc_begin_result(request);
spdk_json_write_array_begin(w);
for (i = 0; i < MAX_ISCSI_CONNECTIONS; i++) {
struct spdk_iscsi_conn *c = &conns[i];
if (!c->is_valid) {
continue;
}
spdk_json_write_object_begin(w);
spdk_json_write_named_int32(w, "id", c->id);
spdk_json_write_named_int32(w, "cid", c->cid);
/*
* If we try to return data for a connection that has not
* logged in yet, the session will not be set. So in this
* case, return -1 for the tsih rather than segfaulting
* on the null c->sess.
*/
if (c->sess == NULL) {
tsih = -1;
} else {
tsih = c->sess->tsih;
}
spdk_json_write_named_int32(w, "tsih", tsih);
spdk_json_write_named_int32(w, "lcore_id", c->lcore);
spdk_json_write_named_string(w, "initiator_addr", c->initiator_addr);
spdk_json_write_named_string(w, "target_addr", c->target_addr);
spdk_json_write_named_string(w, "target_node_name", c->target_short_name);
spdk_json_write_object_end(w);
}
spdk_json_write_array_end(w);
spdk_jsonrpc_end_result(request, w);
}
SPDK_RPC_REGISTER("get_iscsi_connections", spdk_rpc_get_iscsi_connections, SPDK_RPC_RUNTIME)
struct rpc_target_lun {
char *name;
char *bdev_name;
int32_t lun_id;
};
static void
free_rpc_target_lun(struct rpc_target_lun *req)
{
free(req->name);
free(req->bdev_name);
}
static const struct spdk_json_object_decoder rpc_target_lun_decoders[] = {
{"name", offsetof(struct rpc_target_lun, name), spdk_json_decode_string},
{"bdev_name", offsetof(struct rpc_target_lun, bdev_name), spdk_json_decode_string},
{"lun_id", offsetof(struct rpc_target_lun, lun_id), spdk_json_decode_int32, true},
};
static void
spdk_rpc_target_node_add_lun(struct spdk_jsonrpc_request *request,
const struct spdk_json_val *params)
{
struct rpc_target_lun req = {};
struct spdk_json_write_ctx *w;
struct spdk_iscsi_tgt_node *target;
int rc;
req.lun_id = -1;
if (spdk_json_decode_object(params, rpc_target_lun_decoders,
SPDK_COUNTOF(rpc_target_lun_decoders), &req)) {
SPDK_ERRLOG("spdk_json_decode_object failed\n");
goto invalid;
}
target = spdk_iscsi_find_tgt_node(req.name);
if (target == NULL) {
SPDK_ERRLOG("target is not found\n");
goto invalid;
}
rc = spdk_iscsi_tgt_node_add_lun(target, req.bdev_name, req.lun_id);
if (rc < 0) {
SPDK_ERRLOG("add lun failed\n");
goto invalid;
}
free_rpc_target_lun(&req);
w = spdk_jsonrpc_begin_result(request);
spdk_json_write_bool(w, true);
spdk_jsonrpc_end_result(request, w);
return;
invalid:
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
"Invalid parameters");
free_rpc_target_lun(&req);
}
SPDK_RPC_REGISTER("target_node_add_lun", spdk_rpc_target_node_add_lun, SPDK_RPC_RUNTIME)
struct rpc_target_auth {
char *name;
bool disable_chap;
bool require_chap;
bool mutual_chap;
int32_t chap_group;
};
static void
free_rpc_target_auth(struct rpc_target_auth *req)
{
free(req->name);
}
static const struct spdk_json_object_decoder rpc_target_auth_decoders[] = {
{"name", offsetof(struct rpc_target_auth, name), spdk_json_decode_string},
{"disable_chap", offsetof(struct rpc_target_auth, disable_chap), spdk_json_decode_bool, true},
{"require_chap", offsetof(struct rpc_target_auth, require_chap), spdk_json_decode_bool, true},
{"mutual_chap", offsetof(struct rpc_target_auth, mutual_chap), spdk_json_decode_bool, true},
{"chap_group", offsetof(struct rpc_target_auth, chap_group), spdk_json_decode_int32, true},
};
static void
spdk_rpc_set_iscsi_target_node_auth(struct spdk_jsonrpc_request *request,
const struct spdk_json_val *params)
{
struct rpc_target_auth req = {};
struct spdk_json_write_ctx *w;
struct spdk_iscsi_tgt_node *target;
int rc;
if (spdk_json_decode_object(params, rpc_target_auth_decoders,
SPDK_COUNTOF(rpc_target_auth_decoders), &req)) {
SPDK_ERRLOG("spdk_json_decode_object failed\n");
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
"Invalid parameters");
goto exit;
}
target = spdk_iscsi_find_tgt_node(req.name);
if (target == NULL) {
spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
"Could not find target %s", req.name);
goto exit;
}
rc = spdk_iscsi_tgt_node_set_chap_params(target, req.disable_chap, req.require_chap,
req.mutual_chap, req.chap_group);
if (rc < 0) {
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
"Invalid combination of auth params");
goto exit;
}
free_rpc_target_auth(&req);
w = spdk_jsonrpc_begin_result(request);
spdk_json_write_bool(w, true);
spdk_jsonrpc_end_result(request, w);
return;
exit:
free_rpc_target_auth(&req);
}
SPDK_RPC_REGISTER("set_iscsi_target_node_auth", spdk_rpc_set_iscsi_target_node_auth,
SPDK_RPC_RUNTIME)
static void
spdk_rpc_get_iscsi_global_params(struct spdk_jsonrpc_request *request,
const struct spdk_json_val *params)
{
struct spdk_json_write_ctx *w;
if (params != NULL) {
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
"get_iscsi_global_params requires no parameters");
return;
}
w = spdk_jsonrpc_begin_result(request);
spdk_iscsi_opts_info_json(w);
spdk_jsonrpc_end_result(request, w);
}
SPDK_RPC_REGISTER("get_iscsi_global_params", spdk_rpc_get_iscsi_global_params, SPDK_RPC_RUNTIME)
struct rpc_discovery_auth {
bool disable_chap;
bool require_chap;
bool mutual_chap;
int32_t chap_group;
};
static const struct spdk_json_object_decoder rpc_discovery_auth_decoders[] = {
{"disable_chap", offsetof(struct rpc_discovery_auth, disable_chap), spdk_json_decode_bool, true},
{"require_chap", offsetof(struct rpc_discovery_auth, require_chap), spdk_json_decode_bool, true},
{"mutual_chap", offsetof(struct rpc_discovery_auth, mutual_chap), spdk_json_decode_bool, true},
{"chap_group", offsetof(struct rpc_discovery_auth, chap_group), spdk_json_decode_int32, true},
};
static void
spdk_rpc_set_iscsi_discovery_auth(struct spdk_jsonrpc_request *request,
const struct spdk_json_val *params)
{
struct rpc_discovery_auth req = {};
struct spdk_json_write_ctx *w;
int rc;
if (spdk_json_decode_object(params, rpc_discovery_auth_decoders,
SPDK_COUNTOF(rpc_discovery_auth_decoders), &req)) {
SPDK_ERRLOG("spdk_json_decode_object failed\n");
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
"Invalid parameters");
return;
}
rc = spdk_iscsi_set_discovery_auth(req.disable_chap, req.require_chap,
req.mutual_chap, req.chap_group);
if (rc < 0) {
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
"Invalid combination of CHAP params");
return;
}
w = spdk_jsonrpc_begin_result(request);
spdk_json_write_bool(w, true);
spdk_jsonrpc_end_result(request, w);
}
SPDK_RPC_REGISTER("set_iscsi_discovery_auth", spdk_rpc_set_iscsi_discovery_auth, SPDK_RPC_RUNTIME)
#define MAX_AUTH_SECRETS 64
struct rpc_auth_secret {
char *user;
char *secret;
char *muser;
char *msecret;
};
static void
free_rpc_auth_secret(struct rpc_auth_secret *_secret)
{
free(_secret->user);
free(_secret->secret);
free(_secret->muser);
free(_secret->msecret);
}
static const struct spdk_json_object_decoder rpc_auth_secret_decoders[] = {
{"user", offsetof(struct rpc_auth_secret, user), spdk_json_decode_string},
{"secret", offsetof(struct rpc_auth_secret, secret), spdk_json_decode_string},
{"muser", offsetof(struct rpc_auth_secret, muser), spdk_json_decode_string, true},
{"msecret", offsetof(struct rpc_auth_secret, msecret), spdk_json_decode_string, true},
};
static int
decode_rpc_auth_secret(const struct spdk_json_val *val, void *out)
{
struct rpc_auth_secret *_secret = out;
return spdk_json_decode_object(val, rpc_auth_secret_decoders,
SPDK_COUNTOF(rpc_auth_secret_decoders), _secret);
}
struct rpc_auth_secrets {
size_t num_secret;
struct rpc_auth_secret secrets[MAX_AUTH_SECRETS];
};
static void
free_rpc_auth_secrets(struct rpc_auth_secrets *secrets)
{
size_t i;
for (i = 0; i < secrets->num_secret; i++) {
free_rpc_auth_secret(&secrets->secrets[i]);
}
}
static int
decode_rpc_auth_secrets(const struct spdk_json_val *val, void *out)
{
struct rpc_auth_secrets *secrets = out;
return spdk_json_decode_array(val, decode_rpc_auth_secret, secrets->secrets,
MAX_AUTH_SECRETS, &secrets->num_secret,
sizeof(struct rpc_auth_secret));
}
struct rpc_auth_group {
int32_t tag;
struct rpc_auth_secrets secrets;
};
static void
free_rpc_auth_group(struct rpc_auth_group *group)
{
free_rpc_auth_secrets(&group->secrets);
}
static const struct spdk_json_object_decoder rpc_auth_group_decoders[] = {
{"tag", offsetof(struct rpc_auth_group, tag), spdk_json_decode_int32},
{"secrets", offsetof(struct rpc_auth_group, secrets), decode_rpc_auth_secrets, true},
};
static void
spdk_rpc_add_iscsi_auth_group(struct spdk_jsonrpc_request *request,
const struct spdk_json_val *params)
{
struct rpc_auth_group req = {};
struct rpc_auth_secret *_secret;
struct spdk_json_write_ctx *w;
struct spdk_iscsi_auth_group *group = NULL;
int rc;
size_t i;
if (spdk_json_decode_object(params, rpc_auth_group_decoders,
SPDK_COUNTOF(rpc_auth_group_decoders), &req)) {
SPDK_ERRLOG("spdk_json_decode_object failed\n");
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
"Invalid parameters");
free_rpc_auth_group(&req);
return;
}
pthread_mutex_lock(&g_spdk_iscsi.mutex);
rc = spdk_iscsi_add_auth_group(req.tag, &group);
if (rc != 0) {
pthread_mutex_unlock(&g_spdk_iscsi.mutex);
spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
"Could not add auth group (%d), %s",
req.tag, spdk_strerror(-rc));
free_rpc_auth_group(&req);
return;
}
for (i = 0; i < req.secrets.num_secret; i++) {
_secret = &req.secrets.secrets[i];
rc = spdk_iscsi_auth_group_add_secret(group, _secret->user, _secret->secret,
_secret->muser, _secret->msecret);
if (rc != 0) {
spdk_iscsi_delete_auth_group(group);
pthread_mutex_unlock(&g_spdk_iscsi.mutex);
spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
"Could not add secret to auth group (%d), %s",
req.tag, spdk_strerror(-rc));
free_rpc_auth_group(&req);
return;
}
}
pthread_mutex_unlock(&g_spdk_iscsi.mutex);
free_rpc_auth_group(&req);
w = spdk_jsonrpc_begin_result(request);
spdk_json_write_bool(w, true);
spdk_jsonrpc_end_result(request, w);
}
SPDK_RPC_REGISTER("add_iscsi_auth_group", spdk_rpc_add_iscsi_auth_group, SPDK_RPC_RUNTIME)
struct rpc_delete_auth_group {
int32_t tag;
};
static const struct spdk_json_object_decoder rpc_delete_auth_group_decoders[] = {
{"tag", offsetof(struct rpc_delete_auth_group, tag), spdk_json_decode_int32},
};
static void
spdk_rpc_delete_iscsi_auth_group(struct spdk_jsonrpc_request *request,
const struct spdk_json_val *params)
{
struct rpc_delete_auth_group req = {};
struct spdk_json_write_ctx *w;
struct spdk_iscsi_auth_group *group;
if (spdk_json_decode_object(params, rpc_delete_auth_group_decoders,
SPDK_COUNTOF(rpc_delete_auth_group_decoders), &req)) {
SPDK_ERRLOG("spdk_json_decode_object failed\n");
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
"Invalid parameters");
return;
}
pthread_mutex_lock(&g_spdk_iscsi.mutex);
group = spdk_iscsi_find_auth_group_by_tag(req.tag);
if (group == NULL) {
pthread_mutex_unlock(&g_spdk_iscsi.mutex);
spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
"Could not find auth group (%d)", req.tag);
return;
}
spdk_iscsi_delete_auth_group(group);
pthread_mutex_unlock(&g_spdk_iscsi.mutex);
w = spdk_jsonrpc_begin_result(request);
spdk_json_write_bool(w, true);
spdk_jsonrpc_end_result(request, w);
}
SPDK_RPC_REGISTER("delete_iscsi_auth_group", spdk_rpc_delete_iscsi_auth_group, SPDK_RPC_RUNTIME)
struct rpc_add_auth_secret {
int32_t tag;
char *user;
char *secret;
char *muser;
char *msecret;
};
static void
free_rpc_add_auth_secret(struct rpc_add_auth_secret *_secret)
{
free(_secret->user);
free(_secret->secret);
free(_secret->muser);
free(_secret->msecret);
}
static const struct spdk_json_object_decoder rpc_add_auth_secret_decoders[] = {
{"tag", offsetof(struct rpc_add_auth_secret, tag), spdk_json_decode_int32},
{"user", offsetof(struct rpc_add_auth_secret, user), spdk_json_decode_string},
{"secret", offsetof(struct rpc_add_auth_secret, secret), spdk_json_decode_string},
{"muser", offsetof(struct rpc_add_auth_secret, muser), spdk_json_decode_string, true},
{"msecret", offsetof(struct rpc_add_auth_secret, msecret), spdk_json_decode_string, true},
};
static void
spdk_rpc_add_secret_to_iscsi_auth_group(struct spdk_jsonrpc_request *request,
const struct spdk_json_val *params)
{
struct rpc_add_auth_secret req = {};
struct spdk_json_write_ctx *w;
struct spdk_iscsi_auth_group *group;
int rc;
if (spdk_json_decode_object(params, rpc_add_auth_secret_decoders,
SPDK_COUNTOF(rpc_add_auth_secret_decoders), &req)) {
SPDK_ERRLOG("spdk_json_decode_object failed\n");
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
"Invalid parameters");
free_rpc_add_auth_secret(&req);
return;
}
pthread_mutex_lock(&g_spdk_iscsi.mutex);
group = spdk_iscsi_find_auth_group_by_tag(req.tag);
if (group == NULL) {
pthread_mutex_unlock(&g_spdk_iscsi.mutex);
spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
"Could not find auth group (%d)", req.tag);
free_rpc_add_auth_secret(&req);
return;
}
rc = spdk_iscsi_auth_group_add_secret(group, req.user, req.secret, req.muser, req.msecret);
if (rc != 0) {
pthread_mutex_unlock(&g_spdk_iscsi.mutex);
spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
"Could not add secret to auth group (%d), %s",
req.tag, spdk_strerror(-rc));
free_rpc_add_auth_secret(&req);
return;
}
pthread_mutex_unlock(&g_spdk_iscsi.mutex);
free_rpc_add_auth_secret(&req);
w = spdk_jsonrpc_begin_result(request);
spdk_json_write_bool(w, true);
spdk_jsonrpc_end_result(request, w);
}
SPDK_RPC_REGISTER("add_secret_to_iscsi_auth_group", spdk_rpc_add_secret_to_iscsi_auth_group,
SPDK_RPC_RUNTIME)
struct rpc_delete_auth_secret {
int32_t tag;
char *user;
};
static void
free_rpc_delete_auth_secret(struct rpc_delete_auth_secret *_secret)
{
free(_secret->user);
}
static const struct spdk_json_object_decoder rpc_delete_auth_secret_decoders[] = {
{"tag", offsetof(struct rpc_delete_auth_secret, tag), spdk_json_decode_int32},
{"user", offsetof(struct rpc_delete_auth_secret, user), spdk_json_decode_string},
};
static void
spdk_rpc_delete_secret_from_iscsi_auth_group(struct spdk_jsonrpc_request *request,
const struct spdk_json_val *params)
{
struct rpc_delete_auth_secret req = {};
struct spdk_json_write_ctx *w;
struct spdk_iscsi_auth_group *group;
int rc;
if (spdk_json_decode_object(params, rpc_delete_auth_secret_decoders,
SPDK_COUNTOF(rpc_delete_auth_secret_decoders), &req)) {
SPDK_ERRLOG("spdk_json_decode_object failed\n");
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
"Invalid parameters");
free_rpc_delete_auth_secret(&req);
return;
}
pthread_mutex_lock(&g_spdk_iscsi.mutex);
group = spdk_iscsi_find_auth_group_by_tag(req.tag);
if (group == NULL) {
pthread_mutex_unlock(&g_spdk_iscsi.mutex);
spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
"Could not find auth group (%d)", req.tag);
free_rpc_delete_auth_secret(&req);
return;
}
rc = spdk_iscsi_auth_group_delete_secret(group, req.user);
if (rc != 0) {
pthread_mutex_unlock(&g_spdk_iscsi.mutex);
spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
"Could not delete secret from CHAP group (%d), %s",
req.tag, spdk_strerror(-rc));
free_rpc_delete_auth_secret(&req);
return;
}
pthread_mutex_unlock(&g_spdk_iscsi.mutex);
free_rpc_delete_auth_secret(&req);
w = spdk_jsonrpc_begin_result(request);
spdk_json_write_bool(w, true);
spdk_jsonrpc_end_result(request, w);
}
SPDK_RPC_REGISTER("delete_secret_from_iscsi_auth_group",
spdk_rpc_delete_secret_from_iscsi_auth_group, SPDK_RPC_RUNTIME)
static void
spdk_rpc_get_iscsi_auth_groups(struct spdk_jsonrpc_request *request,
const struct spdk_json_val *params)
{
struct spdk_json_write_ctx *w;
if (params != NULL) {
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
"get_iscsi_auth_groups requires no parameters");
return;
}
w = spdk_jsonrpc_begin_result(request);
spdk_json_write_array_begin(w);
spdk_iscsi_auth_groups_info_json(w);
spdk_json_write_array_end(w);
spdk_jsonrpc_end_result(request, w);
}
SPDK_RPC_REGISTER("get_iscsi_auth_groups", spdk_rpc_get_iscsi_auth_groups, SPDK_RPC_RUNTIME)