xref: /spdk/module/bdev/iscsi/bdev_iscsi_rpc.c (revision fecffda6ecf8853b82edccde429b68252f0a62c5)
1 /*   SPDX-License-Identifier: BSD-3-Clause
2  *   Copyright (C) 2018 Intel Corporation.
3  *   All rights reserved.
4  */
5 
6 #include "bdev_iscsi.h"
7 #include "spdk/rpc.h"
8 #include "spdk/util.h"
9 #include "spdk/string.h"
10 
11 #include "spdk/log.h"
12 
13 static const struct spdk_json_object_decoder rpc_bdev_iscsi_options_decoders[] = {
14 	{"timeout_sec", offsetof(struct spdk_bdev_iscsi_opts, timeout_sec), spdk_json_decode_uint64, true},
15 };
16 
17 static void
18 rpc_bdev_iscsi_set_options(struct spdk_jsonrpc_request *request,
19 			   const struct spdk_json_val *params)
20 {
21 	struct spdk_bdev_iscsi_opts opts;
22 	int rc;
23 
24 	bdev_iscsi_get_opts(&opts);
25 	if (params && spdk_json_decode_object(params, rpc_bdev_iscsi_options_decoders,
26 					      SPDK_COUNTOF(rpc_bdev_iscsi_options_decoders),
27 					      &opts)) {
28 		SPDK_ERRLOG("spdk_json_decode_object failed\n");
29 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
30 						 "spdk_json_decode_object failed");
31 		return;
32 	}
33 
34 	rc = bdev_iscsi_set_opts(&opts);
35 	if (rc == -EPERM) {
36 		spdk_jsonrpc_send_error_response(request, -EPERM,
37 						 "RPC not permitted with iscsi already connected");
38 	} else if (rc) {
39 		spdk_jsonrpc_send_error_response(request, rc, spdk_strerror(-rc));
40 	} else {
41 		spdk_jsonrpc_send_bool_response(request, true);
42 	}
43 
44 	return;
45 }
46 SPDK_RPC_REGISTER("bdev_iscsi_set_options", rpc_bdev_iscsi_set_options,
47 		  SPDK_RPC_STARTUP | SPDK_RPC_RUNTIME)
48 
49 struct rpc_bdev_iscsi_create {
50 	char *name;
51 	char *initiator_iqn;
52 	char *url;
53 };
54 
55 static const struct spdk_json_object_decoder rpc_bdev_iscsi_create_decoders[] = {
56 	{"name", offsetof(struct rpc_bdev_iscsi_create, name), spdk_json_decode_string},
57 	{"initiator_iqn", offsetof(struct rpc_bdev_iscsi_create, initiator_iqn), spdk_json_decode_string},
58 	{"url", offsetof(struct rpc_bdev_iscsi_create, url), spdk_json_decode_string},
59 };
60 
61 static void
62 free_rpc_bdev_iscsi_create(struct rpc_bdev_iscsi_create *req)
63 {
64 	free(req->name);
65 	free(req->initiator_iqn);
66 	free(req->url);
67 }
68 
69 static void
70 bdev_iscsi_create_cb(void *cb_arg, struct spdk_bdev *bdev, int status)
71 {
72 	struct spdk_jsonrpc_request *request = cb_arg;
73 	struct spdk_json_write_ctx *w;
74 
75 	if (status > 0) {
76 		spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
77 						     "iSCSI error (%d).", status);
78 	} else if (status < 0) {
79 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
80 						 spdk_strerror(-status));
81 	} else {
82 		w = spdk_jsonrpc_begin_result(request);
83 		spdk_json_write_string(w, spdk_bdev_get_name(bdev));
84 		spdk_jsonrpc_end_result(request, w);
85 	}
86 }
87 
88 static void
89 rpc_bdev_iscsi_create(struct spdk_jsonrpc_request *request,
90 		      const struct spdk_json_val *params)
91 {
92 	struct rpc_bdev_iscsi_create req = {};
93 	int rc = 0;
94 
95 	if (spdk_json_decode_object(params, rpc_bdev_iscsi_create_decoders,
96 				    SPDK_COUNTOF(rpc_bdev_iscsi_create_decoders),
97 				    &req)) {
98 		SPDK_ERRLOG("spdk_json_decode_object failed\n");
99 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
100 						 "spdk_json_decode_object failed");
101 		goto cleanup;
102 	}
103 
104 	rc = create_iscsi_disk(req.name, req.url, req.initiator_iqn, bdev_iscsi_create_cb, request);
105 	if (rc) {
106 		spdk_jsonrpc_send_error_response(request, rc, spdk_strerror(-rc));
107 	}
108 
109 cleanup:
110 	free_rpc_bdev_iscsi_create(&req);
111 }
112 SPDK_RPC_REGISTER("bdev_iscsi_create", rpc_bdev_iscsi_create, SPDK_RPC_RUNTIME)
113 
114 struct rpc_delete_iscsi {
115 	char *name;
116 };
117 
118 static void
119 free_rpc_delete_iscsi(struct rpc_delete_iscsi *r)
120 {
121 	free(r->name);
122 }
123 
124 static const struct spdk_json_object_decoder rpc_delete_iscsi_decoders[] = {
125 	{"name", offsetof(struct rpc_delete_iscsi, name), spdk_json_decode_string},
126 };
127 
128 static void
129 rpc_bdev_iscsi_delete_cb(void *cb_arg, int bdeverrno)
130 {
131 	struct spdk_jsonrpc_request *request = cb_arg;
132 
133 	if (bdeverrno == 0) {
134 		spdk_jsonrpc_send_bool_response(request, true);
135 	} else {
136 		spdk_jsonrpc_send_error_response(request, bdeverrno, spdk_strerror(-bdeverrno));
137 	}
138 }
139 
140 static void
141 rpc_bdev_iscsi_delete(struct spdk_jsonrpc_request *request,
142 		      const struct spdk_json_val *params)
143 {
144 	struct rpc_delete_iscsi req = {NULL};
145 
146 	if (spdk_json_decode_object(params, rpc_delete_iscsi_decoders,
147 				    SPDK_COUNTOF(rpc_delete_iscsi_decoders),
148 				    &req)) {
149 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
150 						 "spdk_json_decode_object failed");
151 		goto cleanup;
152 	}
153 
154 	delete_iscsi_disk(req.name, rpc_bdev_iscsi_delete_cb, request);
155 
156 cleanup:
157 	free_rpc_delete_iscsi(&req);
158 }
159 SPDK_RPC_REGISTER("bdev_iscsi_delete", rpc_bdev_iscsi_delete, SPDK_RPC_RUNTIME)
160