1488570ebSJim Harris /* SPDX-License-Identifier: BSD-3-Clause
2*a6dbe372Spaul luse * Copyright (C) 2018 Intel Corporation.
307fe6a43SSeth Howell * All rights reserved.
407fe6a43SSeth Howell */
507fe6a43SSeth Howell
607fe6a43SSeth Howell #include "bdev_iscsi.h"
707fe6a43SSeth Howell #include "spdk/rpc.h"
807fe6a43SSeth Howell #include "spdk/util.h"
907fe6a43SSeth Howell #include "spdk/string.h"
1007fe6a43SSeth Howell
114e8e97c8STomasz Zawadzki #include "spdk/log.h"
1207fe6a43SSeth Howell
131519aa47Sgongwei static const struct spdk_json_object_decoder rpc_bdev_iscsi_options_decoders[] = {
14c8e594c2Sgongwei {"timeout_sec", offsetof(struct spdk_bdev_iscsi_opts, timeout_sec), spdk_json_decode_uint64, true},
151519aa47Sgongwei };
161519aa47Sgongwei
171519aa47Sgongwei static void
rpc_bdev_iscsi_set_options(struct spdk_jsonrpc_request * request,const struct spdk_json_val * params)181519aa47Sgongwei rpc_bdev_iscsi_set_options(struct spdk_jsonrpc_request *request,
191519aa47Sgongwei const struct spdk_json_val *params)
201519aa47Sgongwei {
211519aa47Sgongwei struct spdk_bdev_iscsi_opts opts;
221519aa47Sgongwei int rc;
231519aa47Sgongwei
241519aa47Sgongwei bdev_iscsi_get_opts(&opts);
251519aa47Sgongwei if (params && spdk_json_decode_object(params, rpc_bdev_iscsi_options_decoders,
261519aa47Sgongwei SPDK_COUNTOF(rpc_bdev_iscsi_options_decoders),
271519aa47Sgongwei &opts)) {
281519aa47Sgongwei SPDK_ERRLOG("spdk_json_decode_object failed\n");
291519aa47Sgongwei spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
301519aa47Sgongwei "spdk_json_decode_object failed");
311519aa47Sgongwei return;
321519aa47Sgongwei }
331519aa47Sgongwei
341519aa47Sgongwei rc = bdev_iscsi_set_opts(&opts);
351519aa47Sgongwei if (rc == -EPERM) {
361519aa47Sgongwei spdk_jsonrpc_send_error_response(request, -EPERM,
371519aa47Sgongwei "RPC not permitted with iscsi already connected");
381519aa47Sgongwei } else if (rc) {
391519aa47Sgongwei spdk_jsonrpc_send_error_response(request, rc, spdk_strerror(-rc));
401519aa47Sgongwei } else {
411519aa47Sgongwei spdk_jsonrpc_send_bool_response(request, true);
421519aa47Sgongwei }
431519aa47Sgongwei
441519aa47Sgongwei return;
451519aa47Sgongwei }
461519aa47Sgongwei SPDK_RPC_REGISTER("bdev_iscsi_set_options", rpc_bdev_iscsi_set_options,
471519aa47Sgongwei SPDK_RPC_STARTUP | SPDK_RPC_RUNTIME)
481519aa47Sgongwei
499f5cbf4cSMaciej Wawryk struct rpc_bdev_iscsi_create {
5007fe6a43SSeth Howell char *name;
5107fe6a43SSeth Howell char *initiator_iqn;
5207fe6a43SSeth Howell char *url;
5307fe6a43SSeth Howell };
5407fe6a43SSeth Howell
559f5cbf4cSMaciej Wawryk static const struct spdk_json_object_decoder rpc_bdev_iscsi_create_decoders[] = {
569f5cbf4cSMaciej Wawryk {"name", offsetof(struct rpc_bdev_iscsi_create, name), spdk_json_decode_string},
579f5cbf4cSMaciej Wawryk {"initiator_iqn", offsetof(struct rpc_bdev_iscsi_create, initiator_iqn), spdk_json_decode_string},
589f5cbf4cSMaciej Wawryk {"url", offsetof(struct rpc_bdev_iscsi_create, url), spdk_json_decode_string},
5907fe6a43SSeth Howell };
6007fe6a43SSeth Howell
6107fe6a43SSeth Howell static void
free_rpc_bdev_iscsi_create(struct rpc_bdev_iscsi_create * req)629f5cbf4cSMaciej Wawryk free_rpc_bdev_iscsi_create(struct rpc_bdev_iscsi_create *req)
6307fe6a43SSeth Howell {
6407fe6a43SSeth Howell free(req->name);
6507fe6a43SSeth Howell free(req->initiator_iqn);
6607fe6a43SSeth Howell free(req->url);
6707fe6a43SSeth Howell }
6807fe6a43SSeth Howell
6907fe6a43SSeth Howell static void
bdev_iscsi_create_cb(void * cb_arg,struct spdk_bdev * bdev,int status)709f5cbf4cSMaciej Wawryk bdev_iscsi_create_cb(void *cb_arg, struct spdk_bdev *bdev, int status)
7107fe6a43SSeth Howell {
7207fe6a43SSeth Howell struct spdk_jsonrpc_request *request = cb_arg;
7307fe6a43SSeth Howell struct spdk_json_write_ctx *w;
7407fe6a43SSeth Howell
7507fe6a43SSeth Howell if (status > 0) {
7607fe6a43SSeth Howell spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
7707fe6a43SSeth Howell "iSCSI error (%d).", status);
7807fe6a43SSeth Howell } else if (status < 0) {
7907fe6a43SSeth Howell spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
8007fe6a43SSeth Howell spdk_strerror(-status));
8107fe6a43SSeth Howell } else {
8207fe6a43SSeth Howell w = spdk_jsonrpc_begin_result(request);
8307fe6a43SSeth Howell spdk_json_write_string(w, spdk_bdev_get_name(bdev));
8407fe6a43SSeth Howell spdk_jsonrpc_end_result(request, w);
8507fe6a43SSeth Howell }
8607fe6a43SSeth Howell }
8707fe6a43SSeth Howell
8807fe6a43SSeth Howell static void
rpc_bdev_iscsi_create(struct spdk_jsonrpc_request * request,const struct spdk_json_val * params)89af44c224SSeth Howell rpc_bdev_iscsi_create(struct spdk_jsonrpc_request *request,
9007fe6a43SSeth Howell const struct spdk_json_val *params)
9107fe6a43SSeth Howell {
929f5cbf4cSMaciej Wawryk struct rpc_bdev_iscsi_create req = {};
9307fe6a43SSeth Howell int rc = 0;
9407fe6a43SSeth Howell
959f5cbf4cSMaciej Wawryk if (spdk_json_decode_object(params, rpc_bdev_iscsi_create_decoders,
969f5cbf4cSMaciej Wawryk SPDK_COUNTOF(rpc_bdev_iscsi_create_decoders),
9707fe6a43SSeth Howell &req)) {
9807fe6a43SSeth Howell SPDK_ERRLOG("spdk_json_decode_object failed\n");
9907fe6a43SSeth Howell spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
10007fe6a43SSeth Howell "spdk_json_decode_object failed");
10107fe6a43SSeth Howell goto cleanup;
10207fe6a43SSeth Howell }
10307fe6a43SSeth Howell
1049f5cbf4cSMaciej Wawryk rc = create_iscsi_disk(req.name, req.url, req.initiator_iqn, bdev_iscsi_create_cb, request);
10507fe6a43SSeth Howell if (rc) {
10607fe6a43SSeth Howell spdk_jsonrpc_send_error_response(request, rc, spdk_strerror(-rc));
10707fe6a43SSeth Howell }
10807fe6a43SSeth Howell
10907fe6a43SSeth Howell cleanup:
1109f5cbf4cSMaciej Wawryk free_rpc_bdev_iscsi_create(&req);
11107fe6a43SSeth Howell }
112af44c224SSeth Howell SPDK_RPC_REGISTER("bdev_iscsi_create", rpc_bdev_iscsi_create, SPDK_RPC_RUNTIME)
11307fe6a43SSeth Howell
11407fe6a43SSeth Howell struct rpc_delete_iscsi {
11507fe6a43SSeth Howell char *name;
11607fe6a43SSeth Howell };
11707fe6a43SSeth Howell
11807fe6a43SSeth Howell static void
free_rpc_delete_iscsi(struct rpc_delete_iscsi * r)11907fe6a43SSeth Howell free_rpc_delete_iscsi(struct rpc_delete_iscsi *r)
12007fe6a43SSeth Howell {
12107fe6a43SSeth Howell free(r->name);
12207fe6a43SSeth Howell }
12307fe6a43SSeth Howell
12407fe6a43SSeth Howell static const struct spdk_json_object_decoder rpc_delete_iscsi_decoders[] = {
12507fe6a43SSeth Howell {"name", offsetof(struct rpc_delete_iscsi, name), spdk_json_decode_string},
12607fe6a43SSeth Howell };
12707fe6a43SSeth Howell
12807fe6a43SSeth Howell static void
rpc_bdev_iscsi_delete_cb(void * cb_arg,int bdeverrno)129af44c224SSeth Howell rpc_bdev_iscsi_delete_cb(void *cb_arg, int bdeverrno)
13007fe6a43SSeth Howell {
13107fe6a43SSeth Howell struct spdk_jsonrpc_request *request = cb_arg;
13207fe6a43SSeth Howell
133d3e394aeSShuhei Matsumoto if (bdeverrno == 0) {
134d3e394aeSShuhei Matsumoto spdk_jsonrpc_send_bool_response(request, true);
135d3e394aeSShuhei Matsumoto } else {
136d3e394aeSShuhei Matsumoto spdk_jsonrpc_send_error_response(request, bdeverrno, spdk_strerror(-bdeverrno));
137d3e394aeSShuhei Matsumoto }
13807fe6a43SSeth Howell }
13907fe6a43SSeth Howell
14007fe6a43SSeth Howell static void
rpc_bdev_iscsi_delete(struct spdk_jsonrpc_request * request,const struct spdk_json_val * params)141af44c224SSeth Howell rpc_bdev_iscsi_delete(struct spdk_jsonrpc_request *request,
14207fe6a43SSeth Howell const struct spdk_json_val *params)
14307fe6a43SSeth Howell {
14407fe6a43SSeth Howell struct rpc_delete_iscsi req = {NULL};
14507fe6a43SSeth Howell
14607fe6a43SSeth Howell if (spdk_json_decode_object(params, rpc_delete_iscsi_decoders,
14707fe6a43SSeth Howell SPDK_COUNTOF(rpc_delete_iscsi_decoders),
14807fe6a43SSeth Howell &req)) {
14907fe6a43SSeth Howell spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
15007fe6a43SSeth Howell "spdk_json_decode_object failed");
15107fe6a43SSeth Howell goto cleanup;
15207fe6a43SSeth Howell }
15307fe6a43SSeth Howell
1544573e4ccSShuhei Matsumoto delete_iscsi_disk(req.name, rpc_bdev_iscsi_delete_cb, request);
15507fe6a43SSeth Howell
15607fe6a43SSeth Howell cleanup:
15707fe6a43SSeth Howell free_rpc_delete_iscsi(&req);
15807fe6a43SSeth Howell }
159af44c224SSeth Howell SPDK_RPC_REGISTER("bdev_iscsi_delete", rpc_bdev_iscsi_delete, SPDK_RPC_RUNTIME)
160