]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | /*- |
2 | * BSD LICENSE | |
3 | * | |
4 | * Copyright (C) 2008-2012 Daisuke Aoyama <aoyama@peach.ne.jp>. | |
5 | * Copyright (c) Intel Corporation. | |
6 | * All rights reserved. | |
7 | * | |
8 | * Redistribution and use in source and binary forms, with or without | |
9 | * modification, are permitted provided that the following conditions | |
10 | * are met: | |
11 | * | |
12 | * * Redistributions of source code must retain the above copyright | |
13 | * notice, this list of conditions and the following disclaimer. | |
14 | * * Redistributions in binary form must reproduce the above copyright | |
15 | * notice, this list of conditions and the following disclaimer in | |
16 | * the documentation and/or other materials provided with the | |
17 | * distribution. | |
18 | * * Neither the name of Intel Corporation nor the names of its | |
19 | * contributors may be used to endorse or promote products derived | |
20 | * from this software without specific prior written permission. | |
21 | * | |
22 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
23 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
24 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
25 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
26 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
27 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
28 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
29 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
30 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
31 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
32 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
33 | */ | |
34 | ||
35 | #include "iscsi/iscsi.h" | |
36 | #include "iscsi/conn.h" | |
37 | #include "iscsi/tgt_node.h" | |
38 | #include "iscsi/portal_grp.h" | |
39 | #include "iscsi/init_grp.h" | |
40 | ||
41 | #include "spdk/rpc.h" | |
42 | #include "spdk/util.h" | |
11fdf7f2 TL |
43 | #include "spdk/event.h" |
44 | #include "spdk/string.h" | |
7c673cae FG |
45 | #include "spdk_internal/log.h" |
46 | ||
47 | static void | |
11fdf7f2 TL |
48 | spdk_rpc_get_initiator_groups(struct spdk_jsonrpc_request *request, |
49 | const struct spdk_json_val *params) | |
7c673cae FG |
50 | { |
51 | struct spdk_json_write_ctx *w; | |
7c673cae FG |
52 | |
53 | if (params != NULL) { | |
11fdf7f2 | 54 | spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, |
7c673cae FG |
55 | "get_initiator_groups requires no parameters"); |
56 | return; | |
57 | } | |
58 | ||
11fdf7f2 TL |
59 | w = spdk_jsonrpc_begin_result(request); |
60 | if (w == NULL) { | |
7c673cae FG |
61 | return; |
62 | } | |
63 | ||
7c673cae | 64 | spdk_json_write_array_begin(w); |
11fdf7f2 | 65 | spdk_iscsi_init_grps_info_json(w); |
7c673cae FG |
66 | spdk_json_write_array_end(w); |
67 | ||
11fdf7f2 | 68 | spdk_jsonrpc_end_result(request, w); |
7c673cae | 69 | } |
11fdf7f2 | 70 | SPDK_RPC_REGISTER("get_initiator_groups", spdk_rpc_get_initiator_groups, SPDK_RPC_RUNTIME) |
7c673cae FG |
71 | |
72 | struct rpc_initiator_list { | |
73 | size_t num_initiators; | |
74 | char *initiators[MAX_INITIATOR]; | |
75 | }; | |
76 | ||
77 | static int | |
78 | decode_rpc_initiator_list(const struct spdk_json_val *val, void *out) | |
79 | { | |
80 | struct rpc_initiator_list *list = out; | |
81 | ||
82 | return spdk_json_decode_array(val, spdk_json_decode_string, list->initiators, MAX_INITIATOR, | |
83 | &list->num_initiators, sizeof(char *)); | |
84 | } | |
85 | ||
86 | static void | |
87 | free_rpc_initiator_list(struct rpc_initiator_list *list) | |
88 | { | |
89 | size_t i; | |
90 | ||
91 | for (i = 0; i < list->num_initiators; i++) { | |
92 | free(list->initiators[i]); | |
93 | } | |
94 | } | |
95 | ||
96 | struct rpc_netmask_list { | |
97 | size_t num_netmasks; | |
98 | char *netmasks[MAX_NETMASK]; | |
99 | }; | |
100 | ||
101 | static int | |
102 | decode_rpc_netmask_list(const struct spdk_json_val *val, void *out) | |
103 | { | |
104 | struct rpc_netmask_list *list = out; | |
105 | ||
106 | return spdk_json_decode_array(val, spdk_json_decode_string, list->netmasks, MAX_NETMASK, | |
107 | &list->num_netmasks, sizeof(char *)); | |
108 | } | |
109 | ||
110 | static void | |
111 | free_rpc_netmask_list(struct rpc_netmask_list *list) | |
112 | { | |
113 | size_t i; | |
114 | ||
115 | for (i = 0; i < list->num_netmasks; i++) { | |
116 | free(list->netmasks[i]); | |
117 | } | |
118 | } | |
119 | ||
120 | struct rpc_initiator_group { | |
121 | int32_t tag; | |
122 | struct rpc_initiator_list initiator_list; | |
123 | struct rpc_netmask_list netmask_list; | |
124 | }; | |
125 | ||
126 | static void | |
127 | free_rpc_initiator_group(struct rpc_initiator_group *ig) | |
128 | { | |
129 | free_rpc_initiator_list(&ig->initiator_list); | |
130 | free_rpc_netmask_list(&ig->netmask_list); | |
131 | } | |
132 | ||
133 | static const struct spdk_json_object_decoder rpc_initiator_group_decoders[] = { | |
134 | {"tag", offsetof(struct rpc_initiator_group, tag), spdk_json_decode_int32}, | |
135 | {"initiators", offsetof(struct rpc_initiator_group, initiator_list), decode_rpc_initiator_list}, | |
136 | {"netmasks", offsetof(struct rpc_initiator_group, netmask_list), decode_rpc_netmask_list}, | |
137 | }; | |
138 | ||
139 | static void | |
11fdf7f2 TL |
140 | spdk_rpc_add_initiator_group(struct spdk_jsonrpc_request *request, |
141 | const struct spdk_json_val *params) | |
7c673cae FG |
142 | { |
143 | struct rpc_initiator_group req = {}; | |
7c673cae FG |
144 | struct spdk_json_write_ctx *w; |
145 | ||
146 | if (spdk_json_decode_object(params, rpc_initiator_group_decoders, | |
147 | SPDK_COUNTOF(rpc_initiator_group_decoders), &req)) { | |
148 | SPDK_ERRLOG("spdk_json_decode_object failed\n"); | |
149 | goto invalid; | |
150 | } | |
151 | ||
152 | if (req.initiator_list.num_initiators == 0 || | |
153 | req.netmask_list.num_netmasks == 0) { | |
154 | goto invalid; | |
155 | } | |
156 | ||
11fdf7f2 TL |
157 | if (spdk_iscsi_init_grp_create_from_initiator_list(req.tag, |
158 | req.initiator_list.num_initiators, | |
159 | req.initiator_list.initiators, | |
160 | req.netmask_list.num_netmasks, | |
161 | req.netmask_list.netmasks)) { | |
162 | SPDK_ERRLOG("create_from_initiator_list failed\n"); | |
7c673cae FG |
163 | goto invalid; |
164 | } | |
11fdf7f2 TL |
165 | |
166 | free_rpc_initiator_group(&req); | |
167 | ||
168 | w = spdk_jsonrpc_begin_result(request); | |
169 | if (w == NULL) { | |
170 | return; | |
7c673cae FG |
171 | } |
172 | ||
11fdf7f2 TL |
173 | spdk_json_write_bool(w, true); |
174 | spdk_jsonrpc_end_result(request, w); | |
175 | return; | |
176 | ||
177 | invalid: | |
178 | spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters"); | |
179 | free_rpc_initiator_group(&req); | |
180 | } | |
181 | SPDK_RPC_REGISTER("add_initiator_group", spdk_rpc_add_initiator_group, SPDK_RPC_RUNTIME) | |
182 | ||
183 | static const struct spdk_json_object_decoder rpc_add_or_delete_initiators_decoders[] = { | |
184 | {"tag", offsetof(struct rpc_initiator_group, tag), spdk_json_decode_int32}, | |
185 | {"initiators", offsetof(struct rpc_initiator_group, initiator_list), decode_rpc_initiator_list, true}, | |
186 | {"netmasks", offsetof(struct rpc_initiator_group, netmask_list), decode_rpc_netmask_list, true}, | |
187 | }; | |
188 | ||
189 | static void | |
190 | spdk_rpc_add_initiators_to_initiator_group(struct spdk_jsonrpc_request *request, | |
191 | const struct spdk_json_val *params) | |
192 | { | |
193 | struct rpc_initiator_group req = {}; | |
194 | struct spdk_json_write_ctx *w; | |
195 | ||
196 | if (spdk_json_decode_object(params, rpc_add_or_delete_initiators_decoders, | |
197 | SPDK_COUNTOF(rpc_add_or_delete_initiators_decoders), &req)) { | |
198 | SPDK_ERRLOG("spdk_json_decode_object failed\n"); | |
7c673cae FG |
199 | goto invalid; |
200 | } | |
7c673cae | 201 | |
11fdf7f2 | 202 | if (spdk_iscsi_init_grp_add_initiators_from_initiator_list(req.tag, |
7c673cae | 203 | req.initiator_list.num_initiators, |
11fdf7f2 | 204 | req.initiator_list.initiators, |
7c673cae | 205 | req.netmask_list.num_netmasks, |
11fdf7f2 TL |
206 | req.netmask_list.netmasks)) { |
207 | SPDK_ERRLOG("add_initiators_from_initiator_list failed\n"); | |
7c673cae FG |
208 | goto invalid; |
209 | } | |
210 | ||
211 | free_rpc_initiator_group(&req); | |
212 | ||
11fdf7f2 TL |
213 | w = spdk_jsonrpc_begin_result(request); |
214 | if (w == NULL) { | |
7c673cae FG |
215 | return; |
216 | } | |
217 | ||
7c673cae | 218 | spdk_json_write_bool(w, true); |
11fdf7f2 | 219 | spdk_jsonrpc_end_result(request, w); |
7c673cae FG |
220 | return; |
221 | ||
222 | invalid: | |
11fdf7f2 TL |
223 | spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters"); |
224 | free_rpc_initiator_group(&req); | |
225 | } | |
226 | SPDK_RPC_REGISTER("add_initiators_to_initiator_group", | |
227 | spdk_rpc_add_initiators_to_initiator_group, SPDK_RPC_RUNTIME) | |
228 | ||
229 | static void | |
230 | spdk_rpc_delete_initiators_from_initiator_group(struct spdk_jsonrpc_request *request, | |
231 | const struct spdk_json_val *params) | |
232 | { | |
233 | struct rpc_initiator_group req = {}; | |
234 | struct spdk_json_write_ctx *w; | |
235 | ||
236 | if (spdk_json_decode_object(params, rpc_add_or_delete_initiators_decoders, | |
237 | SPDK_COUNTOF(rpc_add_or_delete_initiators_decoders), &req)) { | |
238 | SPDK_ERRLOG("spdk_json_decode_object failed\n"); | |
239 | goto invalid; | |
7c673cae | 240 | } |
11fdf7f2 TL |
241 | |
242 | if (spdk_iscsi_init_grp_delete_initiators_from_initiator_list(req.tag, | |
243 | req.initiator_list.num_initiators, | |
244 | req.initiator_list.initiators, | |
245 | req.netmask_list.num_netmasks, | |
246 | req.netmask_list.netmasks)) { | |
247 | SPDK_ERRLOG("delete_initiators_from_initiator_list failed\n"); | |
248 | goto invalid; | |
7c673cae | 249 | } |
11fdf7f2 TL |
250 | |
251 | free_rpc_initiator_group(&req); | |
252 | ||
253 | w = spdk_jsonrpc_begin_result(request); | |
254 | if (w == NULL) { | |
255 | return; | |
256 | } | |
257 | ||
258 | spdk_json_write_bool(w, true); | |
259 | spdk_jsonrpc_end_result(request, w); | |
260 | return; | |
261 | ||
262 | invalid: | |
263 | spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters"); | |
7c673cae FG |
264 | free_rpc_initiator_group(&req); |
265 | } | |
11fdf7f2 TL |
266 | SPDK_RPC_REGISTER("delete_initiators_from_initiator_group", |
267 | spdk_rpc_delete_initiators_from_initiator_group, SPDK_RPC_RUNTIME) | |
7c673cae FG |
268 | |
269 | struct rpc_delete_initiator_group { | |
270 | int32_t tag; | |
271 | }; | |
272 | ||
273 | static const struct spdk_json_object_decoder rpc_delete_initiator_group_decoders[] = { | |
274 | {"tag", offsetof(struct rpc_delete_initiator_group, tag), spdk_json_decode_int32}, | |
275 | }; | |
276 | ||
277 | static void | |
11fdf7f2 TL |
278 | spdk_rpc_delete_initiator_group(struct spdk_jsonrpc_request *request, |
279 | const struct spdk_json_val *params) | |
7c673cae FG |
280 | { |
281 | struct rpc_delete_initiator_group req = {}; | |
282 | struct spdk_json_write_ctx *w; | |
283 | struct spdk_iscsi_init_grp *ig; | |
284 | ||
285 | if (spdk_json_decode_object(params, rpc_delete_initiator_group_decoders, | |
286 | SPDK_COUNTOF(rpc_delete_initiator_group_decoders), | |
287 | &req)) { | |
288 | SPDK_ERRLOG("spdk_json_decode_object failed\n"); | |
289 | goto invalid; | |
290 | } | |
291 | ||
11fdf7f2 | 292 | ig = spdk_iscsi_init_grp_unregister(req.tag); |
7c673cae FG |
293 | if (!ig) { |
294 | goto invalid; | |
295 | } | |
296 | spdk_iscsi_tgt_node_delete_map(NULL, ig); | |
11fdf7f2 | 297 | spdk_iscsi_init_grp_destroy(ig); |
7c673cae | 298 | |
11fdf7f2 TL |
299 | w = spdk_jsonrpc_begin_result(request); |
300 | if (w == NULL) { | |
7c673cae FG |
301 | return; |
302 | } | |
303 | ||
7c673cae | 304 | spdk_json_write_bool(w, true); |
11fdf7f2 | 305 | spdk_jsonrpc_end_result(request, w); |
7c673cae FG |
306 | return; |
307 | ||
308 | invalid: | |
11fdf7f2 | 309 | spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters"); |
7c673cae | 310 | } |
11fdf7f2 | 311 | SPDK_RPC_REGISTER("delete_initiator_group", spdk_rpc_delete_initiator_group, SPDK_RPC_RUNTIME) |
7c673cae FG |
312 | |
313 | static void | |
11fdf7f2 TL |
314 | spdk_rpc_get_target_nodes(struct spdk_jsonrpc_request *request, |
315 | const struct spdk_json_val *params) | |
7c673cae | 316 | { |
7c673cae | 317 | struct spdk_json_write_ctx *w; |
7c673cae FG |
318 | |
319 | if (params != NULL) { | |
11fdf7f2 | 320 | spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, |
7c673cae FG |
321 | "get_target_nodes requires no parameters"); |
322 | return; | |
323 | } | |
324 | ||
11fdf7f2 TL |
325 | w = spdk_jsonrpc_begin_result(request); |
326 | if (w == NULL) { | |
7c673cae FG |
327 | return; |
328 | } | |
329 | ||
7c673cae | 330 | spdk_json_write_array_begin(w); |
11fdf7f2 TL |
331 | spdk_iscsi_tgt_nodes_info_json(w); |
332 | spdk_json_write_array_end(w); | |
7c673cae | 333 | |
11fdf7f2 TL |
334 | spdk_jsonrpc_end_result(request, w); |
335 | } | |
336 | SPDK_RPC_REGISTER("get_target_nodes", spdk_rpc_get_target_nodes, SPDK_RPC_RUNTIME) | |
7c673cae | 337 | |
11fdf7f2 TL |
338 | struct rpc_pg_ig_map { |
339 | int32_t pg_tag; | |
340 | int32_t ig_tag; | |
341 | }; | |
7c673cae | 342 | |
11fdf7f2 TL |
343 | static const struct spdk_json_object_decoder rpc_pg_ig_map_decoders[] = { |
344 | {"pg_tag", offsetof(struct rpc_pg_ig_map, pg_tag), spdk_json_decode_int32}, | |
345 | {"ig_tag", offsetof(struct rpc_pg_ig_map, ig_tag), spdk_json_decode_int32}, | |
346 | }; | |
7c673cae | 347 | |
11fdf7f2 TL |
348 | static int |
349 | decode_rpc_pg_ig_map(const struct spdk_json_val *val, void *out) | |
350 | { | |
351 | struct rpc_pg_ig_map *pg_ig_map = out; | |
7c673cae | 352 | |
11fdf7f2 TL |
353 | return spdk_json_decode_object(val, rpc_pg_ig_map_decoders, |
354 | SPDK_COUNTOF(rpc_pg_ig_map_decoders), | |
355 | pg_ig_map); | |
7c673cae | 356 | } |
7c673cae | 357 | |
11fdf7f2 TL |
358 | struct rpc_pg_ig_maps { |
359 | size_t num_maps; | |
360 | struct rpc_pg_ig_map maps[MAX_TARGET_MAP]; | |
7c673cae FG |
361 | }; |
362 | ||
363 | static int | |
11fdf7f2 | 364 | decode_rpc_pg_ig_maps(const struct spdk_json_val *val, void *out) |
7c673cae | 365 | { |
11fdf7f2 | 366 | struct rpc_pg_ig_maps *pg_ig_maps = out; |
7c673cae | 367 | |
11fdf7f2 TL |
368 | return spdk_json_decode_array(val, decode_rpc_pg_ig_map, pg_ig_maps->maps, |
369 | MAX_TARGET_MAP, &pg_ig_maps->num_maps, | |
370 | sizeof(struct rpc_pg_ig_map)); | |
7c673cae FG |
371 | } |
372 | ||
11fdf7f2 TL |
373 | #define RPC_CONSTRUCT_TARGET_NODE_MAX_LUN 64 |
374 | ||
375 | struct rpc_lun { | |
376 | char *bdev_name; | |
377 | int32_t lun_id; | |
378 | }; | |
379 | ||
380 | static const struct spdk_json_object_decoder rpc_lun_decoders[] = { | |
381 | {"bdev_name", offsetof(struct rpc_lun, bdev_name), spdk_json_decode_string}, | |
382 | {"lun_id", offsetof(struct rpc_lun, lun_id), spdk_json_decode_int32}, | |
7c673cae FG |
383 | }; |
384 | ||
385 | static int | |
11fdf7f2 | 386 | decode_rpc_lun(const struct spdk_json_val *val, void *out) |
7c673cae | 387 | { |
11fdf7f2 | 388 | struct rpc_lun *lun = out; |
7c673cae | 389 | |
11fdf7f2 TL |
390 | return spdk_json_decode_object(val, rpc_lun_decoders, |
391 | SPDK_COUNTOF(rpc_lun_decoders), lun); | |
7c673cae FG |
392 | } |
393 | ||
11fdf7f2 TL |
394 | struct rpc_luns { |
395 | size_t num_luns; | |
396 | struct rpc_lun luns[RPC_CONSTRUCT_TARGET_NODE_MAX_LUN]; | |
7c673cae FG |
397 | }; |
398 | ||
399 | static int | |
11fdf7f2 | 400 | decode_rpc_luns(const struct spdk_json_val *val, void *out) |
7c673cae | 401 | { |
11fdf7f2 | 402 | struct rpc_luns *luns = out; |
7c673cae | 403 | |
11fdf7f2 | 404 | return spdk_json_decode_array(val, decode_rpc_lun, luns->luns, |
7c673cae | 405 | RPC_CONSTRUCT_TARGET_NODE_MAX_LUN, |
11fdf7f2 | 406 | &luns->num_luns, sizeof(struct rpc_lun)); |
7c673cae FG |
407 | } |
408 | ||
409 | static void | |
11fdf7f2 | 410 | free_rpc_luns(struct rpc_luns *p) |
7c673cae FG |
411 | { |
412 | size_t i; | |
413 | ||
11fdf7f2 TL |
414 | for (i = 0; i < p->num_luns; i++) { |
415 | free(p->luns[i].bdev_name); | |
7c673cae FG |
416 | } |
417 | } | |
418 | ||
7c673cae FG |
419 | struct rpc_target_node { |
420 | char *name; | |
421 | char *alias_name; | |
422 | ||
11fdf7f2 TL |
423 | struct rpc_pg_ig_maps pg_ig_maps; |
424 | struct rpc_luns luns; | |
7c673cae FG |
425 | |
426 | int32_t queue_depth; | |
11fdf7f2 TL |
427 | bool disable_chap; |
428 | bool require_chap; | |
429 | bool mutual_chap; | |
430 | int32_t chap_group; | |
431 | ||
432 | bool header_digest; | |
433 | bool data_digest; | |
7c673cae FG |
434 | }; |
435 | ||
436 | static void | |
437 | free_rpc_target_node(struct rpc_target_node *req) | |
438 | { | |
11fdf7f2 TL |
439 | free(req->name); |
440 | free(req->alias_name); | |
441 | free_rpc_luns(&req->luns); | |
7c673cae FG |
442 | } |
443 | ||
444 | static const struct spdk_json_object_decoder rpc_target_node_decoders[] = { | |
445 | {"name", offsetof(struct rpc_target_node, name), spdk_json_decode_string}, | |
446 | {"alias_name", offsetof(struct rpc_target_node, alias_name), spdk_json_decode_string}, | |
11fdf7f2 TL |
447 | {"pg_ig_maps", offsetof(struct rpc_target_node, pg_ig_maps), decode_rpc_pg_ig_maps}, |
448 | {"luns", offsetof(struct rpc_target_node, luns), decode_rpc_luns}, | |
7c673cae | 449 | {"queue_depth", offsetof(struct rpc_target_node, queue_depth), spdk_json_decode_int32}, |
11fdf7f2 TL |
450 | {"disable_chap", offsetof(struct rpc_target_node, disable_chap), spdk_json_decode_bool, true}, |
451 | {"require_chap", offsetof(struct rpc_target_node, require_chap), spdk_json_decode_bool, true}, | |
452 | {"mutual_chap", offsetof(struct rpc_target_node, mutual_chap), spdk_json_decode_bool, true}, | |
453 | {"chap_group", offsetof(struct rpc_target_node, chap_group), spdk_json_decode_int32, true}, | |
454 | {"header_digest", offsetof(struct rpc_target_node, header_digest), spdk_json_decode_bool, true}, | |
455 | {"data_digest", offsetof(struct rpc_target_node, data_digest), spdk_json_decode_bool, true}, | |
7c673cae FG |
456 | }; |
457 | ||
458 | static void | |
11fdf7f2 TL |
459 | spdk_rpc_construct_target_node(struct spdk_jsonrpc_request *request, |
460 | const struct spdk_json_val *params) | |
7c673cae FG |
461 | { |
462 | struct rpc_target_node req = {}; | |
463 | struct spdk_json_write_ctx *w; | |
464 | struct spdk_iscsi_tgt_node *target; | |
11fdf7f2 TL |
465 | int32_t pg_tags[MAX_TARGET_MAP] = {0}, ig_tags[MAX_TARGET_MAP] = {0}; |
466 | char *bdev_names[RPC_CONSTRUCT_TARGET_NODE_MAX_LUN] = {0}; | |
467 | int32_t lun_ids[RPC_CONSTRUCT_TARGET_NODE_MAX_LUN] = {0}; | |
468 | size_t i; | |
7c673cae FG |
469 | |
470 | if (spdk_json_decode_object(params, rpc_target_node_decoders, | |
471 | SPDK_COUNTOF(rpc_target_node_decoders), | |
472 | &req)) { | |
473 | SPDK_ERRLOG("spdk_json_decode_object failed\n"); | |
474 | goto invalid; | |
475 | } | |
476 | ||
11fdf7f2 TL |
477 | for (i = 0; i < req.pg_ig_maps.num_maps; i++) { |
478 | pg_tags[i] = req.pg_ig_maps.maps[i].pg_tag; | |
479 | ig_tags[i] = req.pg_ig_maps.maps[i].ig_tag; | |
7c673cae FG |
480 | } |
481 | ||
11fdf7f2 TL |
482 | for (i = 0; i < req.luns.num_luns; i++) { |
483 | bdev_names[i] = req.luns.luns[i].bdev_name; | |
484 | lun_ids[i] = req.luns.luns[i].lun_id; | |
7c673cae FG |
485 | } |
486 | ||
487 | /* | |
488 | * Use default parameters in a few places: | |
489 | * index = -1 : automatically pick an index for the new target node | |
490 | * alias = NULL | |
7c673cae FG |
491 | */ |
492 | target = spdk_iscsi_tgt_node_construct(-1, req.name, req.alias_name, | |
11fdf7f2 TL |
493 | pg_tags, |
494 | ig_tags, | |
495 | req.pg_ig_maps.num_maps, | |
496 | (const char **)bdev_names, | |
497 | lun_ids, | |
498 | req.luns.num_luns, | |
7c673cae | 499 | req.queue_depth, |
11fdf7f2 TL |
500 | req.disable_chap, |
501 | req.require_chap, | |
502 | req.mutual_chap, | |
503 | req.chap_group, | |
504 | req.header_digest, | |
505 | req.data_digest); | |
7c673cae FG |
506 | |
507 | if (target == NULL) { | |
508 | goto invalid; | |
509 | } | |
510 | ||
511 | free_rpc_target_node(&req); | |
512 | ||
11fdf7f2 TL |
513 | w = spdk_jsonrpc_begin_result(request); |
514 | if (w == NULL) { | |
7c673cae FG |
515 | return; |
516 | } | |
517 | ||
7c673cae | 518 | spdk_json_write_bool(w, true); |
11fdf7f2 | 519 | spdk_jsonrpc_end_result(request, w); |
7c673cae FG |
520 | return; |
521 | ||
522 | invalid: | |
11fdf7f2 | 523 | spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters"); |
7c673cae FG |
524 | free_rpc_target_node(&req); |
525 | } | |
11fdf7f2 TL |
526 | SPDK_RPC_REGISTER("construct_target_node", spdk_rpc_construct_target_node, SPDK_RPC_RUNTIME) |
527 | ||
528 | struct rpc_tgt_node_pg_ig_maps { | |
529 | char *name; | |
530 | struct rpc_pg_ig_maps pg_ig_maps; | |
531 | }; | |
532 | ||
533 | static const struct spdk_json_object_decoder rpc_tgt_node_pg_ig_maps_decoders[] = { | |
534 | {"name", offsetof(struct rpc_tgt_node_pg_ig_maps, name), spdk_json_decode_string}, | |
535 | {"pg_ig_maps", offsetof(struct rpc_tgt_node_pg_ig_maps, pg_ig_maps), decode_rpc_pg_ig_maps}, | |
536 | }; | |
537 | ||
538 | static void | |
539 | spdk_rpc_add_pg_ig_maps(struct spdk_jsonrpc_request *request, | |
540 | const struct spdk_json_val *params) | |
541 | { | |
542 | struct rpc_tgt_node_pg_ig_maps req = {}; | |
543 | struct spdk_json_write_ctx *w; | |
544 | struct spdk_iscsi_tgt_node *target; | |
545 | int32_t pg_tags[MAX_TARGET_MAP] = {0}, ig_tags[MAX_TARGET_MAP] = {0}; | |
546 | size_t i; | |
547 | int rc; | |
548 | ||
549 | if (spdk_json_decode_object(params, rpc_tgt_node_pg_ig_maps_decoders, | |
550 | SPDK_COUNTOF(rpc_tgt_node_pg_ig_maps_decoders), | |
551 | &req)) { | |
552 | SPDK_ERRLOG("spdk_json_decode_object failed\n"); | |
553 | goto invalid; | |
554 | } | |
555 | ||
556 | target = spdk_iscsi_find_tgt_node(req.name); | |
557 | if (target == NULL) { | |
558 | SPDK_ERRLOG("target is not found\n"); | |
559 | goto invalid; | |
560 | } | |
561 | ||
562 | for (i = 0; i < req.pg_ig_maps.num_maps; i++) { | |
563 | pg_tags[i] = req.pg_ig_maps.maps[i].pg_tag; | |
564 | ig_tags[i] = req.pg_ig_maps.maps[i].ig_tag; | |
565 | } | |
566 | ||
567 | rc = spdk_iscsi_tgt_node_add_pg_ig_maps(target, pg_tags, ig_tags, | |
568 | req.pg_ig_maps.num_maps); | |
569 | if (rc < 0) { | |
570 | SPDK_ERRLOG("add pg-ig maps failed\n"); | |
571 | goto invalid; | |
572 | } | |
573 | ||
574 | free(req.name); | |
575 | ||
576 | w = spdk_jsonrpc_begin_result(request); | |
577 | if (w != NULL) { | |
578 | spdk_json_write_bool(w, true); | |
579 | spdk_jsonrpc_end_result(request, w); | |
580 | } | |
581 | return; | |
582 | ||
583 | invalid: | |
584 | spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, | |
585 | "Invalid parameters"); | |
586 | free(req.name); | |
587 | } | |
588 | SPDK_RPC_REGISTER("add_pg_ig_maps", spdk_rpc_add_pg_ig_maps, SPDK_RPC_RUNTIME) | |
589 | ||
590 | static void | |
591 | spdk_rpc_delete_pg_ig_maps(struct spdk_jsonrpc_request *request, | |
592 | const struct spdk_json_val *params) | |
593 | { | |
594 | struct rpc_tgt_node_pg_ig_maps req = {}; | |
595 | struct spdk_json_write_ctx *w; | |
596 | struct spdk_iscsi_tgt_node *target; | |
597 | int32_t pg_tags[MAX_TARGET_MAP] = {0}, ig_tags[MAX_TARGET_MAP] = {0}; | |
598 | size_t i; | |
599 | int rc; | |
600 | ||
601 | if (spdk_json_decode_object(params, rpc_tgt_node_pg_ig_maps_decoders, | |
602 | SPDK_COUNTOF(rpc_tgt_node_pg_ig_maps_decoders), | |
603 | &req)) { | |
604 | SPDK_ERRLOG("spdk_json_decode_object failed\n"); | |
605 | goto invalid; | |
606 | } | |
607 | ||
608 | target = spdk_iscsi_find_tgt_node(req.name); | |
609 | if (target == NULL) { | |
610 | SPDK_ERRLOG("target is not found\n"); | |
611 | goto invalid; | |
612 | } | |
613 | ||
614 | for (i = 0; i < req.pg_ig_maps.num_maps; i++) { | |
615 | pg_tags[i] = req.pg_ig_maps.maps[i].pg_tag; | |
616 | ig_tags[i] = req.pg_ig_maps.maps[i].ig_tag; | |
617 | } | |
618 | ||
619 | rc = spdk_iscsi_tgt_node_delete_pg_ig_maps(target, pg_tags, ig_tags, | |
620 | req.pg_ig_maps.num_maps); | |
621 | if (rc < 0) { | |
622 | SPDK_ERRLOG("remove pg-ig maps failed\n"); | |
623 | goto invalid; | |
624 | } | |
625 | ||
626 | free(req.name); | |
627 | ||
628 | w = spdk_jsonrpc_begin_result(request); | |
629 | if (w != NULL) { | |
630 | spdk_json_write_bool(w, true); | |
631 | spdk_jsonrpc_end_result(request, w); | |
632 | } | |
633 | return; | |
634 | ||
635 | invalid: | |
636 | spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, | |
637 | "Invalid parameters"); | |
638 | free(req.name); | |
639 | } | |
640 | SPDK_RPC_REGISTER("delete_pg_ig_maps", spdk_rpc_delete_pg_ig_maps, SPDK_RPC_RUNTIME) | |
7c673cae FG |
641 | |
642 | struct rpc_delete_target_node { | |
643 | char *name; | |
644 | }; | |
645 | ||
646 | static void | |
647 | free_rpc_delete_target_node(struct rpc_delete_target_node *r) | |
648 | { | |
649 | free(r->name); | |
650 | } | |
651 | ||
652 | static const struct spdk_json_object_decoder rpc_delete_target_node_decoders[] = { | |
653 | {"name", offsetof(struct rpc_delete_target_node, name), spdk_json_decode_string}, | |
654 | }; | |
655 | ||
9f95a23c TL |
656 | struct rpc_delete_target_node_ctx { |
657 | struct rpc_delete_target_node req; | |
658 | struct spdk_jsonrpc_request *request; | |
659 | }; | |
660 | ||
661 | static void | |
662 | rpc_delete_target_node_done(void *cb_arg, int rc) | |
663 | { | |
664 | struct rpc_delete_target_node_ctx *ctx = cb_arg; | |
665 | struct spdk_json_write_ctx *w; | |
666 | ||
667 | free_rpc_delete_target_node(&ctx->req); | |
668 | ||
669 | w = spdk_jsonrpc_begin_result(ctx->request); | |
670 | if (w == NULL) { | |
671 | goto exit; | |
672 | } | |
673 | ||
674 | spdk_json_write_bool(w, rc == 0); | |
675 | spdk_jsonrpc_end_result(ctx->request, w); | |
676 | exit: | |
677 | free(ctx); | |
678 | } | |
679 | ||
7c673cae | 680 | static void |
11fdf7f2 TL |
681 | spdk_rpc_delete_target_node(struct spdk_jsonrpc_request *request, |
682 | const struct spdk_json_val *params) | |
7c673cae | 683 | { |
9f95a23c TL |
684 | struct rpc_delete_target_node_ctx *ctx; |
685 | ||
686 | ctx = calloc(1, sizeof(*ctx)); | |
687 | if (!ctx) { | |
688 | spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, | |
689 | spdk_strerror(ENOMEM)); | |
690 | return; | |
691 | } | |
7c673cae FG |
692 | |
693 | if (spdk_json_decode_object(params, rpc_delete_target_node_decoders, | |
694 | SPDK_COUNTOF(rpc_delete_target_node_decoders), | |
9f95a23c | 695 | &ctx->req)) { |
7c673cae FG |
696 | SPDK_ERRLOG("spdk_json_decode_object failed\n"); |
697 | goto invalid; | |
698 | } | |
699 | ||
9f95a23c | 700 | if (ctx->req.name == NULL) { |
7c673cae FG |
701 | SPDK_ERRLOG("missing name param\n"); |
702 | goto invalid; | |
703 | } | |
704 | ||
9f95a23c | 705 | ctx->request = request; |
7c673cae | 706 | |
9f95a23c TL |
707 | spdk_iscsi_shutdown_tgt_node_by_name(ctx->req.name, |
708 | rpc_delete_target_node_done, ctx); | |
7c673cae FG |
709 | return; |
710 | ||
711 | invalid: | |
11fdf7f2 | 712 | spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters"); |
9f95a23c TL |
713 | free_rpc_delete_target_node(&ctx->req); |
714 | free(ctx); | |
7c673cae | 715 | } |
11fdf7f2 | 716 | SPDK_RPC_REGISTER("delete_target_node", spdk_rpc_delete_target_node, SPDK_RPC_RUNTIME) |
7c673cae FG |
717 | |
718 | static void | |
11fdf7f2 TL |
719 | spdk_rpc_get_portal_groups(struct spdk_jsonrpc_request *request, |
720 | const struct spdk_json_val *params) | |
7c673cae FG |
721 | { |
722 | struct spdk_json_write_ctx *w; | |
7c673cae FG |
723 | |
724 | if (params != NULL) { | |
11fdf7f2 | 725 | spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, |
7c673cae FG |
726 | "get_portal_groups requires no parameters"); |
727 | return; | |
728 | } | |
729 | ||
11fdf7f2 TL |
730 | w = spdk_jsonrpc_begin_result(request); |
731 | if (w == NULL) { | |
7c673cae FG |
732 | return; |
733 | } | |
734 | ||
7c673cae | 735 | spdk_json_write_array_begin(w); |
11fdf7f2 | 736 | spdk_iscsi_portal_grps_info_json(w); |
7c673cae FG |
737 | spdk_json_write_array_end(w); |
738 | ||
11fdf7f2 | 739 | spdk_jsonrpc_end_result(request, w); |
7c673cae | 740 | } |
11fdf7f2 | 741 | SPDK_RPC_REGISTER("get_portal_groups", spdk_rpc_get_portal_groups, SPDK_RPC_RUNTIME) |
7c673cae FG |
742 | |
743 | struct rpc_portal { | |
744 | char *host; | |
745 | char *port; | |
11fdf7f2 | 746 | char *cpumask; |
7c673cae FG |
747 | }; |
748 | ||
749 | struct rpc_portal_list { | |
750 | size_t num_portals; | |
751 | struct rpc_portal portals[MAX_PORTAL]; | |
752 | }; | |
753 | ||
754 | struct rpc_portal_group { | |
755 | int32_t tag; | |
756 | struct rpc_portal_list portal_list; | |
757 | }; | |
758 | ||
759 | static void | |
760 | free_rpc_portal(struct rpc_portal *portal) | |
761 | { | |
762 | free(portal->host); | |
7c673cae | 763 | free(portal->port); |
11fdf7f2 | 764 | free(portal->cpumask); |
7c673cae FG |
765 | } |
766 | ||
767 | static void | |
768 | free_rpc_portal_list(struct rpc_portal_list *pl) | |
769 | { | |
770 | size_t i; | |
771 | ||
772 | for (i = 0; i < pl->num_portals; i++) { | |
773 | free_rpc_portal(&pl->portals[i]); | |
774 | } | |
775 | pl->num_portals = 0; | |
776 | } | |
777 | ||
778 | static void | |
779 | free_rpc_portal_group(struct rpc_portal_group *pg) | |
780 | { | |
781 | free_rpc_portal_list(&pg->portal_list); | |
782 | } | |
783 | ||
784 | static const struct spdk_json_object_decoder rpc_portal_decoders[] = { | |
785 | {"host", offsetof(struct rpc_portal, host), spdk_json_decode_string}, | |
786 | {"port", offsetof(struct rpc_portal, port), spdk_json_decode_string}, | |
11fdf7f2 | 787 | {"cpumask", offsetof(struct rpc_portal, cpumask), spdk_json_decode_string, true}, |
7c673cae FG |
788 | }; |
789 | ||
790 | static int | |
791 | decode_rpc_portal(const struct spdk_json_val *val, void *out) | |
792 | { | |
793 | struct rpc_portal *portal = out; | |
794 | ||
795 | return spdk_json_decode_object(val, rpc_portal_decoders, | |
796 | SPDK_COUNTOF(rpc_portal_decoders), | |
797 | portal); | |
798 | } | |
799 | ||
800 | static int | |
801 | decode_rpc_portal_list(const struct spdk_json_val *val, void *out) | |
802 | { | |
803 | struct rpc_portal_list *list = out; | |
804 | ||
805 | return spdk_json_decode_array(val, decode_rpc_portal, list->portals, MAX_PORTAL, &list->num_portals, | |
806 | sizeof(struct rpc_portal)); | |
807 | } | |
808 | ||
809 | static const struct spdk_json_object_decoder rpc_portal_group_decoders[] = { | |
810 | {"tag", offsetof(struct rpc_portal_group, tag), spdk_json_decode_int32}, | |
811 | {"portals", offsetof(struct rpc_portal_group, portal_list), decode_rpc_portal_list}, | |
812 | }; | |
813 | ||
814 | static void | |
11fdf7f2 TL |
815 | spdk_rpc_add_portal_group(struct spdk_jsonrpc_request *request, |
816 | const struct spdk_json_val *params) | |
7c673cae FG |
817 | { |
818 | struct rpc_portal_group req = {}; | |
11fdf7f2 TL |
819 | struct spdk_iscsi_portal_grp *pg = NULL; |
820 | struct spdk_iscsi_portal *portal; | |
7c673cae | 821 | struct spdk_json_write_ctx *w; |
11fdf7f2 | 822 | size_t i = 0; |
7c673cae FG |
823 | int rc = -1; |
824 | ||
825 | if (spdk_json_decode_object(params, rpc_portal_group_decoders, | |
826 | SPDK_COUNTOF(rpc_portal_group_decoders), | |
827 | &req)) { | |
828 | SPDK_ERRLOG("spdk_json_decode_object failed\n"); | |
829 | goto out; | |
830 | } | |
831 | ||
11fdf7f2 TL |
832 | pg = spdk_iscsi_portal_grp_create(req.tag); |
833 | if (pg == NULL) { | |
834 | SPDK_ERRLOG("portal_grp_create failed\n"); | |
835 | goto out; | |
836 | } | |
7c673cae | 837 | for (i = 0; i < req.portal_list.num_portals; i++) { |
11fdf7f2 TL |
838 | portal = spdk_iscsi_portal_create(req.portal_list.portals[i].host, |
839 | req.portal_list.portals[i].port, | |
840 | req.portal_list.portals[i].cpumask); | |
841 | if (portal == NULL) { | |
842 | SPDK_ERRLOG("portal_create failed\n"); | |
7c673cae FG |
843 | goto out; |
844 | } | |
11fdf7f2 | 845 | spdk_iscsi_portal_grp_add_portal(pg, portal); |
7c673cae FG |
846 | } |
847 | ||
11fdf7f2 TL |
848 | rc = spdk_iscsi_portal_grp_open(pg); |
849 | if (rc != 0) { | |
850 | SPDK_ERRLOG("portal_grp_open failed\n"); | |
851 | goto out; | |
852 | } | |
7c673cae | 853 | |
11fdf7f2 TL |
854 | rc = spdk_iscsi_portal_grp_register(pg); |
855 | if (rc != 0) { | |
856 | SPDK_ERRLOG("portal_grp_register failed\n"); | |
7c673cae FG |
857 | } |
858 | ||
859 | out: | |
860 | if (rc == 0) { | |
11fdf7f2 TL |
861 | w = spdk_jsonrpc_begin_result(request); |
862 | if (w != NULL) { | |
7c673cae | 863 | spdk_json_write_bool(w, true); |
11fdf7f2 | 864 | spdk_jsonrpc_end_result(request, w); |
7c673cae FG |
865 | } |
866 | } else { | |
11fdf7f2 | 867 | spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters"); |
7c673cae | 868 | |
11fdf7f2 TL |
869 | if (pg != NULL) { |
870 | spdk_iscsi_portal_grp_release(pg); | |
7c673cae FG |
871 | } |
872 | } | |
873 | free_rpc_portal_group(&req); | |
874 | } | |
11fdf7f2 | 875 | SPDK_RPC_REGISTER("add_portal_group", spdk_rpc_add_portal_group, SPDK_RPC_RUNTIME) |
7c673cae FG |
876 | |
877 | struct rpc_delete_portal_group { | |
878 | int32_t tag; | |
879 | }; | |
880 | ||
881 | static const struct spdk_json_object_decoder rpc_delete_portal_group_decoders[] = { | |
882 | {"tag", offsetof(struct rpc_delete_portal_group, tag), spdk_json_decode_int32}, | |
883 | }; | |
884 | ||
885 | static void | |
11fdf7f2 TL |
886 | spdk_rpc_delete_portal_group(struct spdk_jsonrpc_request *request, |
887 | const struct spdk_json_val *params) | |
7c673cae FG |
888 | { |
889 | struct rpc_delete_portal_group req = {}; | |
890 | struct spdk_json_write_ctx *w; | |
891 | struct spdk_iscsi_portal_grp *pg; | |
892 | ||
893 | if (spdk_json_decode_object(params, rpc_delete_portal_group_decoders, | |
894 | SPDK_COUNTOF(rpc_delete_portal_group_decoders), | |
895 | &req)) { | |
896 | SPDK_ERRLOG("spdk_json_decode_object failed\n"); | |
897 | goto invalid; | |
898 | } | |
899 | ||
11fdf7f2 | 900 | pg = spdk_iscsi_portal_grp_unregister(req.tag); |
7c673cae FG |
901 | if (!pg) { |
902 | goto invalid; | |
903 | } | |
904 | ||
905 | spdk_iscsi_tgt_node_delete_map(pg, NULL); | |
906 | spdk_iscsi_portal_grp_release(pg); | |
907 | ||
11fdf7f2 TL |
908 | w = spdk_jsonrpc_begin_result(request); |
909 | if (w == NULL) { | |
7c673cae FG |
910 | return; |
911 | } | |
912 | ||
7c673cae | 913 | spdk_json_write_bool(w, true); |
11fdf7f2 | 914 | spdk_jsonrpc_end_result(request, w); |
7c673cae FG |
915 | return; |
916 | ||
917 | invalid: | |
11fdf7f2 | 918 | spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters"); |
7c673cae | 919 | } |
11fdf7f2 | 920 | SPDK_RPC_REGISTER("delete_portal_group", spdk_rpc_delete_portal_group, SPDK_RPC_RUNTIME) |
7c673cae FG |
921 | |
922 | static void | |
11fdf7f2 TL |
923 | spdk_rpc_get_iscsi_connections(struct spdk_jsonrpc_request *request, |
924 | const struct spdk_json_val *params) | |
7c673cae FG |
925 | { |
926 | struct spdk_json_write_ctx *w; | |
927 | struct spdk_iscsi_conn *conns = g_conns_array; | |
928 | int i; | |
929 | uint16_t tsih; | |
930 | ||
931 | if (params != NULL) { | |
11fdf7f2 | 932 | spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, |
7c673cae FG |
933 | "get_iscsi_connections requires no parameters"); |
934 | return; | |
935 | } | |
936 | ||
11fdf7f2 TL |
937 | w = spdk_jsonrpc_begin_result(request); |
938 | if (w == NULL) { | |
7c673cae FG |
939 | return; |
940 | } | |
941 | ||
7c673cae FG |
942 | spdk_json_write_array_begin(w); |
943 | ||
944 | for (i = 0; i < MAX_ISCSI_CONNECTIONS; i++) { | |
945 | struct spdk_iscsi_conn *c = &conns[i]; | |
946 | ||
947 | if (!c->is_valid) { | |
948 | continue; | |
949 | } | |
950 | ||
951 | spdk_json_write_object_begin(w); | |
952 | ||
9f95a23c | 953 | spdk_json_write_named_int32(w, "id", c->id); |
7c673cae | 954 | |
9f95a23c | 955 | spdk_json_write_named_int32(w, "cid", c->cid); |
7c673cae FG |
956 | |
957 | /* | |
958 | * If we try to return data for a connection that has not | |
959 | * logged in yet, the session will not be set. So in this | |
960 | * case, return -1 for the tsih rather than segfaulting | |
961 | * on the null c->sess. | |
962 | */ | |
963 | if (c->sess == NULL) { | |
964 | tsih = -1; | |
965 | } else { | |
966 | tsih = c->sess->tsih; | |
967 | } | |
9f95a23c | 968 | spdk_json_write_named_int32(w, "tsih", tsih); |
7c673cae | 969 | |
9f95a23c | 970 | spdk_json_write_named_int32(w, "lcore_id", c->lcore); |
7c673cae | 971 | |
9f95a23c | 972 | spdk_json_write_named_string(w, "initiator_addr", c->initiator_addr); |
7c673cae | 973 | |
9f95a23c | 974 | spdk_json_write_named_string(w, "target_addr", c->target_addr); |
7c673cae | 975 | |
9f95a23c | 976 | spdk_json_write_named_string(w, "target_node_name", c->target_short_name); |
7c673cae FG |
977 | |
978 | spdk_json_write_object_end(w); | |
979 | } | |
980 | spdk_json_write_array_end(w); | |
981 | ||
11fdf7f2 TL |
982 | spdk_jsonrpc_end_result(request, w); |
983 | } | |
984 | SPDK_RPC_REGISTER("get_iscsi_connections", spdk_rpc_get_iscsi_connections, SPDK_RPC_RUNTIME) | |
985 | ||
986 | struct rpc_target_lun { | |
987 | char *name; | |
988 | char *bdev_name; | |
989 | int32_t lun_id; | |
990 | }; | |
991 | ||
992 | static void | |
993 | free_rpc_target_lun(struct rpc_target_lun *req) | |
994 | { | |
995 | free(req->name); | |
996 | free(req->bdev_name); | |
997 | } | |
998 | ||
999 | static const struct spdk_json_object_decoder rpc_target_lun_decoders[] = { | |
1000 | {"name", offsetof(struct rpc_target_lun, name), spdk_json_decode_string}, | |
1001 | {"bdev_name", offsetof(struct rpc_target_lun, bdev_name), spdk_json_decode_string}, | |
1002 | {"lun_id", offsetof(struct rpc_target_lun, lun_id), spdk_json_decode_int32, true}, | |
1003 | }; | |
1004 | ||
1005 | static void | |
1006 | spdk_rpc_target_node_add_lun(struct spdk_jsonrpc_request *request, | |
1007 | const struct spdk_json_val *params) | |
1008 | { | |
1009 | struct rpc_target_lun req = {}; | |
1010 | struct spdk_json_write_ctx *w; | |
1011 | struct spdk_iscsi_tgt_node *target; | |
1012 | int rc; | |
1013 | ||
1014 | req.lun_id = -1; | |
1015 | ||
1016 | if (spdk_json_decode_object(params, rpc_target_lun_decoders, | |
1017 | SPDK_COUNTOF(rpc_target_lun_decoders), &req)) { | |
1018 | SPDK_ERRLOG("spdk_json_decode_object failed\n"); | |
1019 | goto invalid; | |
1020 | } | |
1021 | ||
1022 | target = spdk_iscsi_find_tgt_node(req.name); | |
1023 | if (target == NULL) { | |
1024 | SPDK_ERRLOG("target is not found\n"); | |
1025 | goto invalid; | |
1026 | } | |
1027 | ||
1028 | rc = spdk_iscsi_tgt_node_add_lun(target, req.bdev_name, req.lun_id); | |
1029 | if (rc < 0) { | |
1030 | SPDK_ERRLOG("add lun failed\n"); | |
1031 | goto invalid; | |
1032 | } | |
1033 | ||
1034 | free_rpc_target_lun(&req); | |
1035 | ||
1036 | w = spdk_jsonrpc_begin_result(request); | |
1037 | if (w == NULL) { | |
1038 | return; | |
1039 | } | |
1040 | ||
1041 | spdk_json_write_bool(w, true); | |
1042 | spdk_jsonrpc_end_result(request, w); | |
1043 | return; | |
1044 | ||
1045 | invalid: | |
1046 | spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, | |
1047 | "Invalid parameters"); | |
1048 | free_rpc_target_lun(&req); | |
1049 | } | |
1050 | SPDK_RPC_REGISTER("target_node_add_lun", spdk_rpc_target_node_add_lun, SPDK_RPC_RUNTIME) | |
1051 | ||
1052 | struct rpc_target_auth { | |
1053 | char *name; | |
1054 | bool disable_chap; | |
1055 | bool require_chap; | |
1056 | bool mutual_chap; | |
1057 | int32_t chap_group; | |
1058 | }; | |
1059 | ||
1060 | static void | |
1061 | free_rpc_target_auth(struct rpc_target_auth *req) | |
1062 | { | |
1063 | free(req->name); | |
1064 | } | |
1065 | ||
1066 | static const struct spdk_json_object_decoder rpc_target_auth_decoders[] = { | |
1067 | {"name", offsetof(struct rpc_target_auth, name), spdk_json_decode_string}, | |
1068 | {"disable_chap", offsetof(struct rpc_target_auth, disable_chap), spdk_json_decode_bool, true}, | |
1069 | {"require_chap", offsetof(struct rpc_target_auth, require_chap), spdk_json_decode_bool, true}, | |
1070 | {"mutual_chap", offsetof(struct rpc_target_auth, mutual_chap), spdk_json_decode_bool, true}, | |
1071 | {"chap_group", offsetof(struct rpc_target_auth, chap_group), spdk_json_decode_int32, true}, | |
1072 | }; | |
1073 | ||
1074 | static void | |
1075 | spdk_rpc_set_iscsi_target_node_auth(struct spdk_jsonrpc_request *request, | |
1076 | const struct spdk_json_val *params) | |
1077 | { | |
1078 | struct rpc_target_auth req = {}; | |
1079 | struct spdk_json_write_ctx *w; | |
1080 | struct spdk_iscsi_tgt_node *target; | |
1081 | int rc; | |
1082 | ||
1083 | if (spdk_json_decode_object(params, rpc_target_auth_decoders, | |
1084 | SPDK_COUNTOF(rpc_target_auth_decoders), &req)) { | |
1085 | SPDK_ERRLOG("spdk_json_decode_object failed\n"); | |
1086 | spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, | |
1087 | "Invalid parameters"); | |
9f95a23c | 1088 | goto exit; |
11fdf7f2 TL |
1089 | } |
1090 | ||
1091 | target = spdk_iscsi_find_tgt_node(req.name); | |
1092 | if (target == NULL) { | |
1093 | spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, | |
1094 | "Could not find target %s", req.name); | |
9f95a23c | 1095 | goto exit; |
11fdf7f2 TL |
1096 | } |
1097 | ||
1098 | rc = spdk_iscsi_tgt_node_set_chap_params(target, req.disable_chap, req.require_chap, | |
1099 | req.mutual_chap, req.chap_group); | |
1100 | if (rc < 0) { | |
1101 | spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, | |
1102 | "Invalid combination of auth params"); | |
9f95a23c | 1103 | goto exit; |
11fdf7f2 TL |
1104 | } |
1105 | ||
1106 | free_rpc_target_auth(&req); | |
1107 | ||
1108 | w = spdk_jsonrpc_begin_result(request); | |
1109 | if (w == NULL) { | |
1110 | return; | |
1111 | } | |
1112 | ||
1113 | spdk_json_write_bool(w, true); | |
1114 | spdk_jsonrpc_end_result(request, w); | |
9f95a23c TL |
1115 | return; |
1116 | ||
1117 | exit: | |
1118 | free_rpc_target_auth(&req); | |
11fdf7f2 TL |
1119 | } |
1120 | SPDK_RPC_REGISTER("set_iscsi_target_node_auth", spdk_rpc_set_iscsi_target_node_auth, | |
1121 | SPDK_RPC_RUNTIME) | |
1122 | ||
1123 | static void | |
1124 | spdk_rpc_get_iscsi_global_params(struct spdk_jsonrpc_request *request, | |
1125 | const struct spdk_json_val *params) | |
1126 | { | |
1127 | struct spdk_json_write_ctx *w; | |
1128 | ||
1129 | if (params != NULL) { | |
1130 | spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, | |
1131 | "get_iscsi_global_params requires no parameters"); | |
1132 | return; | |
1133 | } | |
1134 | ||
1135 | w = spdk_jsonrpc_begin_result(request); | |
1136 | if (w == NULL) { | |
1137 | return; | |
1138 | } | |
1139 | ||
1140 | spdk_iscsi_opts_info_json(w); | |
1141 | ||
1142 | spdk_jsonrpc_end_result(request, w); | |
1143 | } | |
1144 | SPDK_RPC_REGISTER("get_iscsi_global_params", spdk_rpc_get_iscsi_global_params, SPDK_RPC_RUNTIME) | |
1145 | ||
1146 | struct rpc_discovery_auth { | |
1147 | bool disable_chap; | |
1148 | bool require_chap; | |
1149 | bool mutual_chap; | |
1150 | int32_t chap_group; | |
1151 | }; | |
1152 | ||
1153 | static const struct spdk_json_object_decoder rpc_discovery_auth_decoders[] = { | |
1154 | {"disable_chap", offsetof(struct rpc_discovery_auth, disable_chap), spdk_json_decode_bool, true}, | |
1155 | {"require_chap", offsetof(struct rpc_discovery_auth, require_chap), spdk_json_decode_bool, true}, | |
1156 | {"mutual_chap", offsetof(struct rpc_discovery_auth, mutual_chap), spdk_json_decode_bool, true}, | |
1157 | {"chap_group", offsetof(struct rpc_discovery_auth, chap_group), spdk_json_decode_int32, true}, | |
1158 | }; | |
1159 | ||
1160 | static void | |
1161 | spdk_rpc_set_iscsi_discovery_auth(struct spdk_jsonrpc_request *request, | |
1162 | const struct spdk_json_val *params) | |
1163 | { | |
1164 | struct rpc_discovery_auth req = {}; | |
1165 | struct spdk_json_write_ctx *w; | |
1166 | int rc; | |
1167 | ||
1168 | if (spdk_json_decode_object(params, rpc_discovery_auth_decoders, | |
1169 | SPDK_COUNTOF(rpc_discovery_auth_decoders), &req)) { | |
1170 | SPDK_ERRLOG("spdk_json_decode_object failed\n"); | |
1171 | spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, | |
1172 | "Invalid parameters"); | |
1173 | return; | |
1174 | } | |
1175 | ||
1176 | rc = spdk_iscsi_set_discovery_auth(req.disable_chap, req.require_chap, | |
1177 | req.mutual_chap, req.chap_group); | |
1178 | if (rc < 0) { | |
1179 | spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, | |
1180 | "Invalid combination of CHAP params"); | |
1181 | return; | |
1182 | } | |
1183 | ||
1184 | w = spdk_jsonrpc_begin_result(request); | |
1185 | if (w == NULL) { | |
1186 | return; | |
1187 | } | |
1188 | ||
1189 | spdk_json_write_bool(w, true); | |
1190 | spdk_jsonrpc_end_result(request, w); | |
1191 | } | |
1192 | SPDK_RPC_REGISTER("set_iscsi_discovery_auth", spdk_rpc_set_iscsi_discovery_auth, SPDK_RPC_RUNTIME) | |
1193 | ||
1194 | ||
1195 | #define MAX_AUTH_SECRETS 64 | |
1196 | ||
1197 | struct rpc_auth_secret { | |
1198 | char *user; | |
1199 | char *secret; | |
1200 | char *muser; | |
1201 | char *msecret; | |
1202 | }; | |
1203 | ||
1204 | static void | |
1205 | free_rpc_auth_secret(struct rpc_auth_secret *_secret) | |
1206 | { | |
1207 | free(_secret->user); | |
1208 | free(_secret->secret); | |
1209 | free(_secret->muser); | |
1210 | free(_secret->msecret); | |
1211 | } | |
1212 | ||
1213 | static const struct spdk_json_object_decoder rpc_auth_secret_decoders[] = { | |
1214 | {"user", offsetof(struct rpc_auth_secret, user), spdk_json_decode_string}, | |
1215 | {"secret", offsetof(struct rpc_auth_secret, secret), spdk_json_decode_string}, | |
1216 | {"muser", offsetof(struct rpc_auth_secret, muser), spdk_json_decode_string, true}, | |
1217 | {"msecret", offsetof(struct rpc_auth_secret, msecret), spdk_json_decode_string, true}, | |
1218 | }; | |
1219 | ||
1220 | static int | |
1221 | decode_rpc_auth_secret(const struct spdk_json_val *val, void *out) | |
1222 | { | |
1223 | struct rpc_auth_secret *_secret = out; | |
1224 | ||
1225 | return spdk_json_decode_object(val, rpc_auth_secret_decoders, | |
1226 | SPDK_COUNTOF(rpc_auth_secret_decoders), _secret); | |
1227 | } | |
1228 | ||
1229 | struct rpc_auth_secrets { | |
1230 | size_t num_secret; | |
1231 | struct rpc_auth_secret secrets[MAX_AUTH_SECRETS]; | |
1232 | }; | |
1233 | ||
1234 | static void | |
1235 | free_rpc_auth_secrets(struct rpc_auth_secrets *secrets) | |
1236 | { | |
1237 | size_t i; | |
1238 | ||
1239 | for (i = 0; i < secrets->num_secret; i++) { | |
1240 | free_rpc_auth_secret(&secrets->secrets[i]); | |
1241 | } | |
1242 | } | |
1243 | ||
1244 | static int | |
1245 | decode_rpc_auth_secrets(const struct spdk_json_val *val, void *out) | |
1246 | { | |
1247 | struct rpc_auth_secrets *secrets = out; | |
1248 | ||
1249 | return spdk_json_decode_array(val, decode_rpc_auth_secret, secrets->secrets, | |
1250 | MAX_AUTH_SECRETS, &secrets->num_secret, | |
1251 | sizeof(struct rpc_auth_secret)); | |
1252 | } | |
1253 | ||
1254 | struct rpc_auth_group { | |
1255 | int32_t tag; | |
1256 | struct rpc_auth_secrets secrets; | |
1257 | }; | |
1258 | ||
1259 | static void | |
1260 | free_rpc_auth_group(struct rpc_auth_group *group) | |
1261 | { | |
1262 | free_rpc_auth_secrets(&group->secrets); | |
1263 | } | |
1264 | ||
1265 | static const struct spdk_json_object_decoder rpc_auth_group_decoders[] = { | |
1266 | {"tag", offsetof(struct rpc_auth_group, tag), spdk_json_decode_int32}, | |
1267 | {"secrets", offsetof(struct rpc_auth_group, secrets), decode_rpc_auth_secrets, true}, | |
1268 | }; | |
1269 | ||
1270 | static void | |
1271 | spdk_rpc_add_iscsi_auth_group(struct spdk_jsonrpc_request *request, | |
1272 | const struct spdk_json_val *params) | |
1273 | { | |
1274 | struct rpc_auth_group req = {}; | |
1275 | struct rpc_auth_secret *_secret; | |
1276 | struct spdk_json_write_ctx *w; | |
1277 | struct spdk_iscsi_auth_group *group = NULL; | |
1278 | int rc; | |
1279 | size_t i; | |
1280 | ||
1281 | if (spdk_json_decode_object(params, rpc_auth_group_decoders, | |
1282 | SPDK_COUNTOF(rpc_auth_group_decoders), &req)) { | |
1283 | SPDK_ERRLOG("spdk_json_decode_object failed\n"); | |
1284 | spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, | |
1285 | "Invalid parameters"); | |
1286 | free_rpc_auth_group(&req); | |
1287 | return; | |
1288 | } | |
1289 | ||
1290 | pthread_mutex_lock(&g_spdk_iscsi.mutex); | |
1291 | ||
1292 | rc = spdk_iscsi_add_auth_group(req.tag, &group); | |
1293 | if (rc != 0) { | |
1294 | pthread_mutex_unlock(&g_spdk_iscsi.mutex); | |
1295 | ||
1296 | spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, | |
1297 | "Could not add auth group (%d), %s", | |
1298 | req.tag, spdk_strerror(-rc)); | |
1299 | free_rpc_auth_group(&req); | |
1300 | return; | |
1301 | } | |
1302 | ||
1303 | for (i = 0; i < req.secrets.num_secret; i++) { | |
1304 | _secret = &req.secrets.secrets[i]; | |
1305 | rc = spdk_iscsi_auth_group_add_secret(group, _secret->user, _secret->secret, | |
1306 | _secret->muser, _secret->msecret); | |
1307 | if (rc != 0) { | |
1308 | spdk_iscsi_delete_auth_group(group); | |
1309 | pthread_mutex_unlock(&g_spdk_iscsi.mutex); | |
1310 | ||
1311 | spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, | |
1312 | "Could not add secret to auth group (%d), %s", | |
1313 | req.tag, spdk_strerror(-rc)); | |
1314 | free_rpc_auth_group(&req); | |
1315 | return; | |
1316 | } | |
1317 | } | |
1318 | ||
1319 | pthread_mutex_unlock(&g_spdk_iscsi.mutex); | |
1320 | ||
1321 | free_rpc_auth_group(&req); | |
1322 | ||
1323 | w = spdk_jsonrpc_begin_result(request); | |
1324 | if (w == NULL) { | |
1325 | return; | |
1326 | } | |
1327 | ||
1328 | spdk_json_write_bool(w, true); | |
1329 | spdk_jsonrpc_end_result(request, w); | |
1330 | } | |
1331 | SPDK_RPC_REGISTER("add_iscsi_auth_group", spdk_rpc_add_iscsi_auth_group, SPDK_RPC_RUNTIME) | |
1332 | ||
1333 | struct rpc_delete_auth_group { | |
1334 | int32_t tag; | |
1335 | }; | |
1336 | ||
1337 | static const struct spdk_json_object_decoder rpc_delete_auth_group_decoders[] = { | |
1338 | {"tag", offsetof(struct rpc_delete_auth_group, tag), spdk_json_decode_int32}, | |
1339 | }; | |
1340 | ||
1341 | static void | |
1342 | spdk_rpc_delete_iscsi_auth_group(struct spdk_jsonrpc_request *request, | |
1343 | const struct spdk_json_val *params) | |
1344 | { | |
1345 | struct rpc_delete_auth_group req = {}; | |
1346 | struct spdk_json_write_ctx *w; | |
1347 | struct spdk_iscsi_auth_group *group; | |
1348 | ||
1349 | if (spdk_json_decode_object(params, rpc_delete_auth_group_decoders, | |
1350 | SPDK_COUNTOF(rpc_delete_auth_group_decoders), &req)) { | |
1351 | SPDK_ERRLOG("spdk_json_decode_object failed\n"); | |
1352 | spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, | |
1353 | "Invalid parameters"); | |
1354 | return; | |
1355 | } | |
1356 | ||
1357 | pthread_mutex_lock(&g_spdk_iscsi.mutex); | |
1358 | ||
1359 | group = spdk_iscsi_find_auth_group_by_tag(req.tag); | |
1360 | if (group == NULL) { | |
1361 | pthread_mutex_unlock(&g_spdk_iscsi.mutex); | |
1362 | ||
1363 | spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, | |
1364 | "Could not find auth group (%d)", req.tag); | |
1365 | return; | |
1366 | } | |
1367 | ||
1368 | spdk_iscsi_delete_auth_group(group); | |
1369 | ||
1370 | pthread_mutex_unlock(&g_spdk_iscsi.mutex); | |
1371 | ||
1372 | w = spdk_jsonrpc_begin_result(request); | |
1373 | if (w == NULL) { | |
1374 | return; | |
1375 | } | |
1376 | ||
1377 | spdk_json_write_bool(w, true); | |
1378 | spdk_jsonrpc_end_result(request, w); | |
1379 | } | |
1380 | SPDK_RPC_REGISTER("delete_iscsi_auth_group", spdk_rpc_delete_iscsi_auth_group, SPDK_RPC_RUNTIME) | |
1381 | ||
1382 | struct rpc_add_auth_secret { | |
1383 | int32_t tag; | |
1384 | char *user; | |
1385 | char *secret; | |
1386 | char *muser; | |
1387 | char *msecret; | |
1388 | }; | |
1389 | ||
1390 | static void | |
1391 | free_rpc_add_auth_secret(struct rpc_add_auth_secret *_secret) | |
1392 | { | |
1393 | free(_secret->user); | |
1394 | free(_secret->secret); | |
1395 | free(_secret->muser); | |
1396 | free(_secret->msecret); | |
1397 | } | |
1398 | ||
1399 | static const struct spdk_json_object_decoder rpc_add_auth_secret_decoders[] = { | |
1400 | {"tag", offsetof(struct rpc_add_auth_secret, tag), spdk_json_decode_int32}, | |
1401 | {"user", offsetof(struct rpc_add_auth_secret, user), spdk_json_decode_string}, | |
1402 | {"secret", offsetof(struct rpc_add_auth_secret, secret), spdk_json_decode_string}, | |
1403 | {"muser", offsetof(struct rpc_add_auth_secret, muser), spdk_json_decode_string, true}, | |
1404 | {"msecret", offsetof(struct rpc_add_auth_secret, msecret), spdk_json_decode_string, true}, | |
1405 | }; | |
1406 | ||
1407 | static void | |
1408 | spdk_rpc_add_secret_to_iscsi_auth_group(struct spdk_jsonrpc_request *request, | |
1409 | const struct spdk_json_val *params) | |
1410 | { | |
1411 | struct rpc_add_auth_secret req = {}; | |
1412 | struct spdk_json_write_ctx *w; | |
1413 | struct spdk_iscsi_auth_group *group; | |
1414 | int rc; | |
1415 | ||
1416 | if (spdk_json_decode_object(params, rpc_add_auth_secret_decoders, | |
1417 | SPDK_COUNTOF(rpc_add_auth_secret_decoders), &req)) { | |
1418 | SPDK_ERRLOG("spdk_json_decode_object failed\n"); | |
1419 | spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, | |
1420 | "Invalid parameters"); | |
1421 | free_rpc_add_auth_secret(&req); | |
1422 | return; | |
1423 | } | |
1424 | ||
1425 | pthread_mutex_lock(&g_spdk_iscsi.mutex); | |
1426 | ||
1427 | group = spdk_iscsi_find_auth_group_by_tag(req.tag); | |
1428 | if (group == NULL) { | |
1429 | pthread_mutex_unlock(&g_spdk_iscsi.mutex); | |
1430 | ||
1431 | spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, | |
1432 | "Could not find auth group (%d)", req.tag); | |
1433 | free_rpc_add_auth_secret(&req); | |
1434 | return; | |
1435 | } | |
1436 | ||
1437 | rc = spdk_iscsi_auth_group_add_secret(group, req.user, req.secret, req.muser, req.msecret); | |
1438 | if (rc != 0) { | |
1439 | pthread_mutex_unlock(&g_spdk_iscsi.mutex); | |
1440 | ||
1441 | spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, | |
1442 | "Could not add secret to auth group (%d), %s", | |
1443 | req.tag, spdk_strerror(-rc)); | |
1444 | free_rpc_add_auth_secret(&req); | |
1445 | return; | |
1446 | } | |
1447 | ||
1448 | pthread_mutex_unlock(&g_spdk_iscsi.mutex); | |
1449 | ||
1450 | free_rpc_add_auth_secret(&req); | |
1451 | ||
1452 | w = spdk_jsonrpc_begin_result(request); | |
1453 | if (w == NULL) { | |
1454 | return; | |
1455 | } | |
1456 | ||
1457 | spdk_json_write_bool(w, true); | |
1458 | spdk_jsonrpc_end_result(request, w); | |
1459 | } | |
1460 | SPDK_RPC_REGISTER("add_secret_to_iscsi_auth_group", spdk_rpc_add_secret_to_iscsi_auth_group, | |
1461 | SPDK_RPC_RUNTIME) | |
1462 | ||
1463 | struct rpc_delete_auth_secret { | |
1464 | int32_t tag; | |
1465 | char *user; | |
1466 | }; | |
1467 | ||
1468 | static void | |
1469 | free_rpc_delete_auth_secret(struct rpc_delete_auth_secret *_secret) | |
1470 | { | |
1471 | free(_secret->user); | |
1472 | } | |
1473 | ||
1474 | static const struct spdk_json_object_decoder rpc_delete_auth_secret_decoders[] = { | |
1475 | {"tag", offsetof(struct rpc_delete_auth_secret, tag), spdk_json_decode_int32}, | |
1476 | {"user", offsetof(struct rpc_delete_auth_secret, user), spdk_json_decode_string}, | |
1477 | }; | |
1478 | ||
1479 | static void | |
1480 | spdk_rpc_delete_secret_from_iscsi_auth_group(struct spdk_jsonrpc_request *request, | |
1481 | const struct spdk_json_val *params) | |
1482 | { | |
1483 | struct rpc_delete_auth_secret req = {}; | |
1484 | struct spdk_json_write_ctx *w; | |
1485 | struct spdk_iscsi_auth_group *group; | |
1486 | int rc; | |
1487 | ||
1488 | if (spdk_json_decode_object(params, rpc_delete_auth_secret_decoders, | |
1489 | SPDK_COUNTOF(rpc_delete_auth_secret_decoders), &req)) { | |
1490 | SPDK_ERRLOG("spdk_json_decode_object failed\n"); | |
1491 | spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, | |
1492 | "Invalid parameters"); | |
1493 | free_rpc_delete_auth_secret(&req); | |
1494 | return; | |
1495 | } | |
1496 | ||
1497 | pthread_mutex_lock(&g_spdk_iscsi.mutex); | |
1498 | ||
1499 | group = spdk_iscsi_find_auth_group_by_tag(req.tag); | |
1500 | if (group == NULL) { | |
1501 | pthread_mutex_unlock(&g_spdk_iscsi.mutex); | |
1502 | ||
1503 | spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, | |
1504 | "Could not find auth group (%d)", req.tag); | |
1505 | free_rpc_delete_auth_secret(&req); | |
1506 | return; | |
1507 | } | |
1508 | ||
1509 | rc = spdk_iscsi_auth_group_delete_secret(group, req.user); | |
1510 | if (rc != 0) { | |
1511 | pthread_mutex_unlock(&g_spdk_iscsi.mutex); | |
1512 | ||
1513 | spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, | |
1514 | "Could not delete secret from CHAP group (%d), %s", | |
1515 | req.tag, spdk_strerror(-rc)); | |
1516 | free_rpc_delete_auth_secret(&req); | |
1517 | return; | |
1518 | } | |
1519 | ||
1520 | pthread_mutex_unlock(&g_spdk_iscsi.mutex); | |
1521 | ||
1522 | free_rpc_delete_auth_secret(&req); | |
1523 | ||
1524 | w = spdk_jsonrpc_begin_result(request); | |
1525 | if (w == NULL) { | |
1526 | return; | |
1527 | } | |
1528 | ||
1529 | spdk_json_write_bool(w, true); | |
1530 | spdk_jsonrpc_end_result(request, w); | |
1531 | } | |
1532 | SPDK_RPC_REGISTER("delete_secret_from_iscsi_auth_group", | |
1533 | spdk_rpc_delete_secret_from_iscsi_auth_group, SPDK_RPC_RUNTIME) | |
1534 | ||
1535 | static void | |
1536 | spdk_rpc_get_iscsi_auth_groups(struct spdk_jsonrpc_request *request, | |
1537 | const struct spdk_json_val *params) | |
1538 | { | |
1539 | struct spdk_json_write_ctx *w; | |
1540 | ||
1541 | if (params != NULL) { | |
1542 | spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, | |
1543 | "get_iscsi_auth_groups requires no parameters"); | |
1544 | return; | |
1545 | } | |
1546 | ||
1547 | w = spdk_jsonrpc_begin_result(request); | |
1548 | if (w == NULL) { | |
1549 | return; | |
1550 | } | |
1551 | ||
1552 | spdk_json_write_array_begin(w); | |
1553 | spdk_iscsi_auth_groups_info_json(w); | |
1554 | spdk_json_write_array_end(w); | |
1555 | ||
1556 | spdk_jsonrpc_end_result(request, w); | |
7c673cae | 1557 | } |
11fdf7f2 | 1558 | SPDK_RPC_REGISTER("get_iscsi_auth_groups", spdk_rpc_get_iscsi_auth_groups, SPDK_RPC_RUNTIME) |