Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright (C) 2008-2012 Daisuke Aoyama <aoyama@peach.ne.jp>.
3 : : * Copyright (C) 2016 Intel Corporation.
4 : : * All rights reserved.
5 : : */
6 : :
7 : : #include "iscsi/iscsi.h"
8 : : #include "iscsi/conn.h"
9 : : #include "iscsi/tgt_node.h"
10 : : #include "iscsi/portal_grp.h"
11 : : #include "iscsi/init_grp.h"
12 : :
13 : : #include "spdk/rpc.h"
14 : : #include "spdk/util.h"
15 : : #include "spdk/string.h"
16 : : #include "spdk/log.h"
17 : :
18 : : static void
19 : 180 : rpc_iscsi_get_initiator_groups(struct spdk_jsonrpc_request *request,
20 : : const struct spdk_json_val *params)
21 : : {
22 : : struct spdk_json_write_ctx *w;
23 : :
24 [ - + ]: 180 : if (params != NULL) {
25 : 0 : spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
26 : : "iscsi_get_initiator_groups requires no parameters");
27 : 0 : return;
28 : : }
29 : :
30 : 180 : w = spdk_jsonrpc_begin_result(request);
31 : 180 : spdk_json_write_array_begin(w);
32 : 180 : iscsi_init_grps_info_json(w);
33 : 180 : spdk_json_write_array_end(w);
34 : :
35 : 180 : spdk_jsonrpc_end_result(request, w);
36 : : }
37 : 588 : SPDK_RPC_REGISTER("iscsi_get_initiator_groups", rpc_iscsi_get_initiator_groups,
38 : : SPDK_RPC_RUNTIME)
39 : :
40 : : struct rpc_initiator_list {
41 : : size_t num_initiators;
42 : : char *initiators[MAX_INITIATOR];
43 : : };
44 : :
45 : : static int
46 : 136 : decode_rpc_initiator_list(const struct spdk_json_val *val, void *out)
47 : : {
48 : 136 : struct rpc_initiator_list *list = out;
49 : :
50 : 136 : return spdk_json_decode_array(val, spdk_json_decode_string, list->initiators, MAX_INITIATOR,
51 : : &list->num_initiators, sizeof(char *));
52 : : }
53 : :
54 : : static void
55 : 136 : free_rpc_initiator_list(struct rpc_initiator_list *list)
56 : : {
57 : : size_t i;
58 : :
59 [ + + ]: 272 : for (i = 0; i < list->num_initiators; i++) {
60 : 136 : free(list->initiators[i]);
61 : : }
62 : 136 : }
63 : :
64 : : struct rpc_netmask_list {
65 : : size_t num_netmasks;
66 : : char *netmasks[MAX_NETMASK];
67 : : };
68 : :
69 : : static int
70 : 136 : decode_rpc_netmask_list(const struct spdk_json_val *val, void *out)
71 : : {
72 : 136 : struct rpc_netmask_list *list = out;
73 : :
74 : 136 : return spdk_json_decode_array(val, spdk_json_decode_string, list->netmasks, MAX_NETMASK,
75 : : &list->num_netmasks, sizeof(char *));
76 : : }
77 : :
78 : : static void
79 : 136 : free_rpc_netmask_list(struct rpc_netmask_list *list)
80 : : {
81 : : size_t i;
82 : :
83 [ + + ]: 272 : for (i = 0; i < list->num_netmasks; i++) {
84 : 136 : free(list->netmasks[i]);
85 : : }
86 : 136 : }
87 : :
88 : : struct rpc_initiator_group {
89 : : int32_t tag;
90 : : struct rpc_initiator_list initiator_list;
91 : : struct rpc_netmask_list netmask_list;
92 : : };
93 : :
94 : : static void
95 : 136 : free_rpc_initiator_group(struct rpc_initiator_group *ig)
96 : : {
97 : 136 : free_rpc_initiator_list(&ig->initiator_list);
98 : 136 : free_rpc_netmask_list(&ig->netmask_list);
99 : 136 : }
100 : :
101 : : static const struct spdk_json_object_decoder rpc_initiator_group_decoders[] = {
102 : : {"tag", offsetof(struct rpc_initiator_group, tag), spdk_json_decode_int32},
103 : : {"initiators", offsetof(struct rpc_initiator_group, initiator_list), decode_rpc_initiator_list},
104 : : {"netmasks", offsetof(struct rpc_initiator_group, netmask_list), decode_rpc_netmask_list},
105 : : };
106 : :
107 : : static void
108 : 88 : rpc_iscsi_create_initiator_group(struct spdk_jsonrpc_request *request,
109 : : const struct spdk_json_val *params)
110 : : {
111 : 88 : struct rpc_initiator_group req = {};
112 : :
113 [ - + ]: 88 : if (spdk_json_decode_object(params, rpc_initiator_group_decoders,
114 : : SPDK_COUNTOF(rpc_initiator_group_decoders), &req)) {
115 : 0 : SPDK_ERRLOG("spdk_json_decode_object failed\n");
116 : 0 : goto invalid;
117 : : }
118 : :
119 [ + - ]: 88 : if (req.initiator_list.num_initiators == 0 ||
120 [ - + ]: 88 : req.netmask_list.num_netmasks == 0) {
121 : 0 : goto invalid;
122 : : }
123 : :
124 [ - + ]: 88 : if (iscsi_init_grp_create_from_initiator_list(req.tag,
125 : 88 : req.initiator_list.num_initiators,
126 : : req.initiator_list.initiators,
127 : 88 : req.netmask_list.num_netmasks,
128 : : req.netmask_list.netmasks)) {
129 : 0 : SPDK_ERRLOG("create_from_initiator_list failed\n");
130 : 0 : goto invalid;
131 : : }
132 : :
133 : 88 : free_rpc_initiator_group(&req);
134 : :
135 : 88 : spdk_jsonrpc_send_bool_response(request, true);
136 : 88 : return;
137 : :
138 : 0 : invalid:
139 : 0 : spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
140 : 0 : free_rpc_initiator_group(&req);
141 : : }
142 : 588 : SPDK_RPC_REGISTER("iscsi_create_initiator_group", rpc_iscsi_create_initiator_group,
143 : : SPDK_RPC_RUNTIME)
144 : :
145 : : static const struct spdk_json_object_decoder rpc_add_or_delete_initiators_decoders[] = {
146 : : {"tag", offsetof(struct rpc_initiator_group, tag), spdk_json_decode_int32},
147 : : {"initiators", offsetof(struct rpc_initiator_group, initiator_list), decode_rpc_initiator_list, true},
148 : : {"netmasks", offsetof(struct rpc_initiator_group, netmask_list), decode_rpc_netmask_list, true},
149 : : };
150 : :
151 : : static void
152 : 24 : rpc_iscsi_initiator_group_add_initiators(struct spdk_jsonrpc_request *request,
153 : : const struct spdk_json_val *params)
154 : : {
155 : 24 : struct rpc_initiator_group req = {};
156 : :
157 [ - + ]: 24 : if (spdk_json_decode_object(params, rpc_add_or_delete_initiators_decoders,
158 : : SPDK_COUNTOF(rpc_add_or_delete_initiators_decoders), &req)) {
159 : 0 : SPDK_ERRLOG("spdk_json_decode_object failed\n");
160 : 0 : goto invalid;
161 : : }
162 : :
163 [ - + ]: 24 : if (iscsi_init_grp_add_initiators_from_initiator_list(req.tag,
164 : 24 : req.initiator_list.num_initiators,
165 : : req.initiator_list.initiators,
166 : 24 : req.netmask_list.num_netmasks,
167 : : req.netmask_list.netmasks)) {
168 : 0 : SPDK_ERRLOG("add_initiators_from_initiator_list failed\n");
169 : 0 : goto invalid;
170 : : }
171 : :
172 : 24 : free_rpc_initiator_group(&req);
173 : :
174 : 24 : spdk_jsonrpc_send_bool_response(request, true);
175 : 24 : return;
176 : :
177 : 0 : invalid:
178 : 0 : spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
179 : 0 : free_rpc_initiator_group(&req);
180 : : }
181 : 588 : SPDK_RPC_REGISTER("iscsi_initiator_group_add_initiators",
182 : : rpc_iscsi_initiator_group_add_initiators, SPDK_RPC_RUNTIME)
183 : :
184 : : static void
185 : 24 : rpc_iscsi_initiator_group_remove_initiators(struct spdk_jsonrpc_request *request,
186 : : const struct spdk_json_val *params)
187 : : {
188 : 24 : struct rpc_initiator_group req = {};
189 : :
190 [ - + ]: 24 : if (spdk_json_decode_object(params, rpc_add_or_delete_initiators_decoders,
191 : : SPDK_COUNTOF(rpc_add_or_delete_initiators_decoders), &req)) {
192 : 0 : SPDK_ERRLOG("spdk_json_decode_object failed\n");
193 : 0 : goto invalid;
194 : : }
195 : :
196 [ - + ]: 24 : if (iscsi_init_grp_delete_initiators_from_initiator_list(req.tag,
197 : 24 : req.initiator_list.num_initiators,
198 : : req.initiator_list.initiators,
199 : 24 : req.netmask_list.num_netmasks,
200 : : req.netmask_list.netmasks)) {
201 : 0 : SPDK_ERRLOG("delete_initiators_from_initiator_list failed\n");
202 : 0 : goto invalid;
203 : : }
204 : :
205 : 24 : free_rpc_initiator_group(&req);
206 : :
207 : 24 : spdk_jsonrpc_send_bool_response(request, true);
208 : 24 : return;
209 : :
210 : 0 : invalid:
211 : 0 : spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
212 : 0 : free_rpc_initiator_group(&req);
213 : : }
214 : 588 : SPDK_RPC_REGISTER("iscsi_initiator_group_remove_initiators",
215 : : rpc_iscsi_initiator_group_remove_initiators, SPDK_RPC_RUNTIME)
216 : :
217 : : struct rpc_iscsi_delete_initiator_group {
218 : : int32_t tag;
219 : : };
220 : :
221 : : static const struct spdk_json_object_decoder rpc_iscsi_delete_initiator_group_decoders[] = {
222 : : {"tag", offsetof(struct rpc_iscsi_delete_initiator_group, tag), spdk_json_decode_int32},
223 : : };
224 : :
225 : : static void
226 : 34 : rpc_iscsi_delete_initiator_group(struct spdk_jsonrpc_request *request,
227 : : const struct spdk_json_val *params)
228 : : {
229 : 34 : struct rpc_iscsi_delete_initiator_group req = {};
230 : : struct spdk_iscsi_init_grp *ig;
231 : :
232 [ - + ]: 34 : if (spdk_json_decode_object(params, rpc_iscsi_delete_initiator_group_decoders,
233 : : SPDK_COUNTOF(rpc_iscsi_delete_initiator_group_decoders),
234 : : &req)) {
235 : 0 : SPDK_ERRLOG("spdk_json_decode_object failed\n");
236 : 0 : goto invalid;
237 : : }
238 : :
239 : 34 : ig = iscsi_init_grp_unregister(req.tag);
240 [ - + ]: 34 : if (!ig) {
241 : 0 : goto invalid;
242 : : }
243 : 34 : iscsi_tgt_node_delete_map(NULL, ig);
244 : 34 : iscsi_init_grp_destroy(ig);
245 : :
246 : 34 : spdk_jsonrpc_send_bool_response(request, true);
247 : 34 : return;
248 : :
249 : 0 : invalid:
250 : 0 : spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
251 : : }
252 : 588 : SPDK_RPC_REGISTER("iscsi_delete_initiator_group", rpc_iscsi_delete_initiator_group,
253 : : SPDK_RPC_RUNTIME)
254 : :
255 : : static void
256 : 142 : rpc_iscsi_get_target_nodes(struct spdk_jsonrpc_request *request,
257 : : const struct spdk_json_val *params)
258 : : {
259 : : struct spdk_json_write_ctx *w;
260 : :
261 [ - + ]: 142 : if (params != NULL) {
262 : 0 : spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
263 : : "iscsi_get_target_nodes requires no parameters");
264 : 0 : return;
265 : : }
266 : :
267 : 142 : w = spdk_jsonrpc_begin_result(request);
268 : 142 : spdk_json_write_array_begin(w);
269 : 142 : iscsi_tgt_nodes_info_json(w);
270 : 142 : spdk_json_write_array_end(w);
271 : :
272 : 142 : spdk_jsonrpc_end_result(request, w);
273 : : }
274 : 588 : SPDK_RPC_REGISTER("iscsi_get_target_nodes", rpc_iscsi_get_target_nodes, SPDK_RPC_RUNTIME)
275 : :
276 : : struct rpc_pg_ig_map {
277 : : int32_t pg_tag;
278 : : int32_t ig_tag;
279 : : };
280 : :
281 : : static const struct spdk_json_object_decoder rpc_pg_ig_map_decoders[] = {
282 : : {"pg_tag", offsetof(struct rpc_pg_ig_map, pg_tag), spdk_json_decode_int32},
283 : : {"ig_tag", offsetof(struct rpc_pg_ig_map, ig_tag), spdk_json_decode_int32},
284 : : };
285 : :
286 : : static int
287 : 166 : decode_rpc_pg_ig_map(const struct spdk_json_val *val, void *out)
288 : : {
289 : 166 : struct rpc_pg_ig_map *pg_ig_map = out;
290 : :
291 : 166 : return spdk_json_decode_object(val, rpc_pg_ig_map_decoders,
292 : : SPDK_COUNTOF(rpc_pg_ig_map_decoders),
293 : : pg_ig_map);
294 : : }
295 : :
296 : : struct rpc_pg_ig_maps {
297 : : size_t num_maps;
298 : : struct rpc_pg_ig_map maps[MAX_TARGET_MAP];
299 : : };
300 : :
301 : : static int
302 : 162 : decode_rpc_pg_ig_maps(const struct spdk_json_val *val, void *out)
303 : : {
304 : 162 : struct rpc_pg_ig_maps *pg_ig_maps = out;
305 : :
306 : 162 : return spdk_json_decode_array(val, decode_rpc_pg_ig_map, pg_ig_maps->maps,
307 : : MAX_TARGET_MAP, &pg_ig_maps->num_maps,
308 : : sizeof(struct rpc_pg_ig_map));
309 : : }
310 : :
311 : : #define RPC_ISCSI_CREATE_TARGET_NODE_MAX_LUN 64
312 : :
313 : : struct rpc_lun {
314 : : char *bdev_name;
315 : : int32_t lun_id;
316 : : };
317 : :
318 : : static const struct spdk_json_object_decoder rpc_lun_decoders[] = {
319 : : {"bdev_name", offsetof(struct rpc_lun, bdev_name), spdk_json_decode_string},
320 : : {"lun_id", offsetof(struct rpc_lun, lun_id), spdk_json_decode_int32},
321 : : };
322 : :
323 : : static int
324 : 342 : decode_rpc_lun(const struct spdk_json_val *val, void *out)
325 : : {
326 : 342 : struct rpc_lun *lun = out;
327 : :
328 : 342 : return spdk_json_decode_object(val, rpc_lun_decoders,
329 : : SPDK_COUNTOF(rpc_lun_decoders), lun);
330 : : }
331 : :
332 : : struct rpc_luns {
333 : : size_t num_luns;
334 : : struct rpc_lun luns[RPC_ISCSI_CREATE_TARGET_NODE_MAX_LUN];
335 : : };
336 : :
337 : : static int
338 : 158 : decode_rpc_luns(const struct spdk_json_val *val, void *out)
339 : : {
340 : 158 : struct rpc_luns *luns = out;
341 : :
342 : 158 : return spdk_json_decode_array(val, decode_rpc_lun, luns->luns,
343 : : RPC_ISCSI_CREATE_TARGET_NODE_MAX_LUN,
344 : : &luns->num_luns, sizeof(struct rpc_lun));
345 : : }
346 : :
347 : : static void
348 : 158 : free_rpc_luns(struct rpc_luns *p)
349 : : {
350 : : size_t i;
351 : :
352 [ + + ]: 500 : for (i = 0; i < p->num_luns; i++) {
353 : 342 : free(p->luns[i].bdev_name);
354 : : }
355 : 158 : }
356 : :
357 : : struct rpc_target_node {
358 : : char *name;
359 : : char *alias_name;
360 : :
361 : : struct rpc_pg_ig_maps pg_ig_maps;
362 : : struct rpc_luns luns;
363 : :
364 : : int32_t queue_depth;
365 : : bool disable_chap;
366 : : bool require_chap;
367 : : bool mutual_chap;
368 : : int32_t chap_group;
369 : :
370 : : bool header_digest;
371 : : bool data_digest;
372 : : };
373 : :
374 : : static void
375 : 158 : free_rpc_target_node(struct rpc_target_node *req)
376 : : {
377 : 158 : free(req->name);
378 : 158 : free(req->alias_name);
379 : 158 : free_rpc_luns(&req->luns);
380 : 158 : }
381 : :
382 : : static const struct spdk_json_object_decoder rpc_target_node_decoders[] = {
383 : : {"name", offsetof(struct rpc_target_node, name), spdk_json_decode_string},
384 : : {"alias_name", offsetof(struct rpc_target_node, alias_name), spdk_json_decode_string},
385 : : {"pg_ig_maps", offsetof(struct rpc_target_node, pg_ig_maps), decode_rpc_pg_ig_maps},
386 : : {"luns", offsetof(struct rpc_target_node, luns), decode_rpc_luns},
387 : : {"queue_depth", offsetof(struct rpc_target_node, queue_depth), spdk_json_decode_int32},
388 : : {"disable_chap", offsetof(struct rpc_target_node, disable_chap), spdk_json_decode_bool, true},
389 : : {"require_chap", offsetof(struct rpc_target_node, require_chap), spdk_json_decode_bool, true},
390 : : {"mutual_chap", offsetof(struct rpc_target_node, mutual_chap), spdk_json_decode_bool, true},
391 : : {"chap_group", offsetof(struct rpc_target_node, chap_group), spdk_json_decode_int32, true},
392 : : {"header_digest", offsetof(struct rpc_target_node, header_digest), spdk_json_decode_bool, true},
393 : : {"data_digest", offsetof(struct rpc_target_node, data_digest), spdk_json_decode_bool, true},
394 : : };
395 : :
396 : : static void
397 : 158 : rpc_iscsi_create_target_node(struct spdk_jsonrpc_request *request,
398 : : const struct spdk_json_val *params)
399 : : {
400 : 158 : struct rpc_target_node req = {};
401 : : struct spdk_iscsi_tgt_node *target;
402 : 158 : int32_t pg_tags[MAX_TARGET_MAP] = {0}, ig_tags[MAX_TARGET_MAP] = {0};
403 : 158 : char *bdev_names[RPC_ISCSI_CREATE_TARGET_NODE_MAX_LUN] = {0};
404 : 158 : int32_t lun_ids[RPC_ISCSI_CREATE_TARGET_NODE_MAX_LUN] = {0};
405 : : size_t i;
406 : :
407 [ - + ]: 158 : if (spdk_json_decode_object(params, rpc_target_node_decoders,
408 : : SPDK_COUNTOF(rpc_target_node_decoders),
409 : : &req)) {
410 : 0 : SPDK_ERRLOG("spdk_json_decode_object failed\n");
411 : 0 : goto invalid;
412 : : }
413 : :
414 [ + + ]: 316 : for (i = 0; i < req.pg_ig_maps.num_maps; i++) {
415 : 158 : pg_tags[i] = req.pg_ig_maps.maps[i].pg_tag;
416 : 158 : ig_tags[i] = req.pg_ig_maps.maps[i].ig_tag;
417 : : }
418 : :
419 [ + + ]: 500 : for (i = 0; i < req.luns.num_luns; i++) {
420 : 342 : bdev_names[i] = req.luns.luns[i].bdev_name;
421 : 342 : lun_ids[i] = req.luns.luns[i].lun_id;
422 : : }
423 : :
424 : : /*
425 : : * Use default parameters in a few places:
426 : : * index = -1 : automatically pick an index for the new target node
427 : : * alias = NULL
428 : : */
429 : 790 : target = iscsi_tgt_node_construct(-1, req.name, req.alias_name,
430 : : pg_tags,
431 : : ig_tags,
432 : 158 : req.pg_ig_maps.num_maps,
433 : : (const char **)bdev_names,
434 : : lun_ids,
435 : 158 : req.luns.num_luns,
436 : : req.queue_depth,
437 : 158 : req.disable_chap,
438 [ - + ]: 158 : req.require_chap,
439 [ - + ]: 158 : req.mutual_chap,
440 : : req.chap_group,
441 [ - + ]: 158 : req.header_digest,
442 [ - + - + ]: 158 : req.data_digest);
443 : :
444 [ - + ]: 158 : if (target == NULL) {
445 : 0 : goto invalid;
446 : : }
447 : :
448 : 158 : free_rpc_target_node(&req);
449 : :
450 : 158 : spdk_jsonrpc_send_bool_response(request, true);
451 : 158 : return;
452 : :
453 : 0 : invalid:
454 : 0 : spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
455 : 0 : free_rpc_target_node(&req);
456 : : }
457 : 588 : SPDK_RPC_REGISTER("iscsi_create_target_node", rpc_iscsi_create_target_node, SPDK_RPC_RUNTIME)
458 : :
459 : : struct rpc_tgt_node_pg_ig_maps {
460 : : char *name;
461 : : struct rpc_pg_ig_maps pg_ig_maps;
462 : : };
463 : :
464 : : static const struct spdk_json_object_decoder rpc_tgt_node_pg_ig_maps_decoders[] = {
465 : : {"name", offsetof(struct rpc_tgt_node_pg_ig_maps, name), spdk_json_decode_string},
466 : : {"pg_ig_maps", offsetof(struct rpc_tgt_node_pg_ig_maps, pg_ig_maps), decode_rpc_pg_ig_maps},
467 : : };
468 : :
469 : : static void
470 : 2 : rpc_iscsi_target_node_add_pg_ig_maps(struct spdk_jsonrpc_request *request,
471 : : const struct spdk_json_val *params)
472 : : {
473 : 2 : struct rpc_tgt_node_pg_ig_maps req = {};
474 : : struct spdk_iscsi_tgt_node *target;
475 : 2 : int32_t pg_tags[MAX_TARGET_MAP] = {0}, ig_tags[MAX_TARGET_MAP] = {0};
476 : : size_t i;
477 : : int rc;
478 : :
479 [ - + ]: 2 : if (spdk_json_decode_object(params, rpc_tgt_node_pg_ig_maps_decoders,
480 : : SPDK_COUNTOF(rpc_tgt_node_pg_ig_maps_decoders),
481 : : &req)) {
482 : 0 : SPDK_ERRLOG("spdk_json_decode_object failed\n");
483 : 0 : goto invalid;
484 : : }
485 : :
486 : 2 : target = iscsi_find_tgt_node(req.name);
487 [ - + ]: 2 : if (target == NULL) {
488 : 0 : SPDK_ERRLOG("target is not found\n");
489 : 0 : goto invalid;
490 : : }
491 : :
492 [ + + ]: 6 : for (i = 0; i < req.pg_ig_maps.num_maps; i++) {
493 : 4 : pg_tags[i] = req.pg_ig_maps.maps[i].pg_tag;
494 : 4 : ig_tags[i] = req.pg_ig_maps.maps[i].ig_tag;
495 : : }
496 : :
497 : 2 : rc = iscsi_target_node_add_pg_ig_maps(target, pg_tags, ig_tags,
498 : 2 : req.pg_ig_maps.num_maps);
499 [ - + ]: 2 : if (rc < 0) {
500 : 0 : SPDK_ERRLOG("add pg-ig maps failed\n");
501 : 0 : goto invalid;
502 : : }
503 : :
504 : 2 : free(req.name);
505 : :
506 : 2 : spdk_jsonrpc_send_bool_response(request, true);
507 : 2 : return;
508 : :
509 : 0 : invalid:
510 : 0 : spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
511 : : "Invalid parameters");
512 : 0 : free(req.name);
513 : : }
514 : 588 : SPDK_RPC_REGISTER("iscsi_target_node_add_pg_ig_maps",
515 : : rpc_iscsi_target_node_add_pg_ig_maps, SPDK_RPC_RUNTIME)
516 : :
517 : : static void
518 : 2 : rpc_iscsi_target_node_remove_pg_ig_maps(struct spdk_jsonrpc_request *request,
519 : : const struct spdk_json_val *params)
520 : : {
521 : 2 : struct rpc_tgt_node_pg_ig_maps req = {};
522 : : struct spdk_iscsi_tgt_node *target;
523 : 2 : int32_t pg_tags[MAX_TARGET_MAP] = {0}, ig_tags[MAX_TARGET_MAP] = {0};
524 : : size_t i;
525 : : int rc;
526 : :
527 [ - + ]: 2 : if (spdk_json_decode_object(params, rpc_tgt_node_pg_ig_maps_decoders,
528 : : SPDK_COUNTOF(rpc_tgt_node_pg_ig_maps_decoders),
529 : : &req)) {
530 : 0 : SPDK_ERRLOG("spdk_json_decode_object failed\n");
531 : 0 : goto invalid;
532 : : }
533 : :
534 : 2 : target = iscsi_find_tgt_node(req.name);
535 [ - + ]: 2 : if (target == NULL) {
536 : 0 : SPDK_ERRLOG("target is not found\n");
537 : 0 : goto invalid;
538 : : }
539 : :
540 [ + + ]: 6 : for (i = 0; i < req.pg_ig_maps.num_maps; i++) {
541 : 4 : pg_tags[i] = req.pg_ig_maps.maps[i].pg_tag;
542 : 4 : ig_tags[i] = req.pg_ig_maps.maps[i].ig_tag;
543 : : }
544 : :
545 : 2 : rc = iscsi_target_node_remove_pg_ig_maps(target, pg_tags, ig_tags,
546 : 2 : req.pg_ig_maps.num_maps);
547 [ - + ]: 2 : if (rc < 0) {
548 : 0 : SPDK_ERRLOG("remove pg-ig maps failed\n");
549 : 0 : goto invalid;
550 : : }
551 : :
552 : 2 : free(req.name);
553 : :
554 : 2 : spdk_jsonrpc_send_bool_response(request, true);
555 : 2 : return;
556 : :
557 : 0 : invalid:
558 : 0 : spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
559 : : "Invalid parameters");
560 : 0 : free(req.name);
561 : : }
562 : 588 : SPDK_RPC_REGISTER("iscsi_target_node_remove_pg_ig_maps",
563 : : rpc_iscsi_target_node_remove_pg_ig_maps, SPDK_RPC_RUNTIME)
564 : :
565 : : struct rpc_iscsi_delete_target_node {
566 : : char *name;
567 : : };
568 : :
569 : : static void
570 : 54 : free_rpc_iscsi_delete_target_node(struct rpc_iscsi_delete_target_node *r)
571 : : {
572 : 54 : free(r->name);
573 : 54 : }
574 : :
575 : : static const struct spdk_json_object_decoder rpc_iscsi_delete_target_node_decoders[] = {
576 : : {"name", offsetof(struct rpc_iscsi_delete_target_node, name), spdk_json_decode_string},
577 : : };
578 : :
579 : : struct rpc_iscsi_delete_target_node_ctx {
580 : : struct rpc_iscsi_delete_target_node req;
581 : : struct spdk_jsonrpc_request *request;
582 : : };
583 : :
584 : : static void
585 : 54 : rpc_iscsi_delete_target_node_done(void *cb_arg, int rc)
586 : : {
587 : 54 : struct rpc_iscsi_delete_target_node_ctx *ctx = cb_arg;
588 : :
589 : 54 : free_rpc_iscsi_delete_target_node(&ctx->req);
590 [ + - ]: 54 : if (rc == 0) {
591 : 54 : spdk_jsonrpc_send_bool_response(ctx->request, true);
592 : : } else {
593 : 0 : spdk_jsonrpc_send_error_response(ctx->request, rc, spdk_strerror(-rc));
594 : : }
595 : 54 : free(ctx);
596 : 54 : }
597 : :
598 : : static void
599 : 54 : rpc_iscsi_delete_target_node(struct spdk_jsonrpc_request *request,
600 : : const struct spdk_json_val *params)
601 : : {
602 : : struct rpc_iscsi_delete_target_node_ctx *ctx;
603 : :
604 : 54 : ctx = calloc(1, sizeof(*ctx));
605 [ - + ]: 54 : if (!ctx) {
606 : 0 : spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
607 : : spdk_strerror(ENOMEM));
608 : 0 : return;
609 : : }
610 : :
611 [ - + ]: 54 : if (spdk_json_decode_object(params, rpc_iscsi_delete_target_node_decoders,
612 : : SPDK_COUNTOF(rpc_iscsi_delete_target_node_decoders),
613 : 54 : &ctx->req)) {
614 : 0 : SPDK_ERRLOG("spdk_json_decode_object failed\n");
615 : 0 : goto invalid;
616 : : }
617 : :
618 [ - + ]: 54 : if (ctx->req.name == NULL) {
619 : 0 : SPDK_ERRLOG("missing name param\n");
620 : 0 : goto invalid;
621 : : }
622 : :
623 : 54 : ctx->request = request;
624 : :
625 : 54 : iscsi_shutdown_tgt_node_by_name(ctx->req.name,
626 : : rpc_iscsi_delete_target_node_done, ctx);
627 : 54 : return;
628 : :
629 : 0 : invalid:
630 : 0 : spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
631 : 0 : free_rpc_iscsi_delete_target_node(&ctx->req);
632 : 0 : free(ctx);
633 : : }
634 : 588 : SPDK_RPC_REGISTER("iscsi_delete_target_node", rpc_iscsi_delete_target_node, SPDK_RPC_RUNTIME)
635 : :
636 : : static void
637 : 136 : rpc_iscsi_get_portal_groups(struct spdk_jsonrpc_request *request,
638 : : const struct spdk_json_val *params)
639 : : {
640 : : struct spdk_json_write_ctx *w;
641 : :
642 [ - + ]: 136 : if (params != NULL) {
643 : 0 : spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
644 : : "iscsi_get_portal_groups requires no parameters");
645 : 0 : return;
646 : : }
647 : :
648 : 136 : w = spdk_jsonrpc_begin_result(request);
649 : 136 : spdk_json_write_array_begin(w);
650 : 136 : iscsi_portal_grps_info_json(w);
651 : 136 : spdk_json_write_array_end(w);
652 : :
653 : 136 : spdk_jsonrpc_end_result(request, w);
654 : : }
655 : 588 : SPDK_RPC_REGISTER("iscsi_get_portal_groups", rpc_iscsi_get_portal_groups, SPDK_RPC_RUNTIME)
656 : :
657 : : struct rpc_portal {
658 : : char *host;
659 : : char *port;
660 : : };
661 : :
662 : : struct rpc_portal_list {
663 : : size_t num_portals;
664 : : struct rpc_portal portals[MAX_PORTAL];
665 : : };
666 : :
667 : : struct rpc_portal_group {
668 : : int32_t tag;
669 : : struct rpc_portal_list portal_list;
670 : : bool is_private;
671 : : bool wait;
672 : : };
673 : :
674 : : static void
675 : 54 : free_rpc_portal(struct rpc_portal *portal)
676 : : {
677 : 54 : free(portal->host);
678 : 54 : free(portal->port);
679 : 54 : }
680 : :
681 : : static void
682 : 52 : free_rpc_portal_list(struct rpc_portal_list *pl)
683 : : {
684 : : size_t i;
685 : :
686 [ + + ]: 106 : for (i = 0; i < pl->num_portals; i++) {
687 : 54 : free_rpc_portal(&pl->portals[i]);
688 : : }
689 : 52 : pl->num_portals = 0;
690 : 52 : }
691 : :
692 : : static void
693 : 52 : free_rpc_portal_group(struct rpc_portal_group *pg)
694 : : {
695 : 52 : free_rpc_portal_list(&pg->portal_list);
696 : 52 : }
697 : :
698 : : static const struct spdk_json_object_decoder rpc_portal_decoders[] = {
699 : : {"host", offsetof(struct rpc_portal, host), spdk_json_decode_string},
700 : : {"port", offsetof(struct rpc_portal, port), spdk_json_decode_string},
701 : : };
702 : :
703 : : static int
704 : 54 : decode_rpc_portal(const struct spdk_json_val *val, void *out)
705 : : {
706 : 54 : struct rpc_portal *portal = out;
707 : :
708 : 54 : return spdk_json_decode_object(val, rpc_portal_decoders,
709 : : SPDK_COUNTOF(rpc_portal_decoders),
710 : : portal);
711 : : }
712 : :
713 : : static int
714 : 52 : decode_rpc_portal_list(const struct spdk_json_val *val, void *out)
715 : : {
716 : 52 : struct rpc_portal_list *list = out;
717 : :
718 : 52 : return spdk_json_decode_array(val, decode_rpc_portal, list->portals, MAX_PORTAL, &list->num_portals,
719 : : sizeof(struct rpc_portal));
720 : : }
721 : :
722 : : static const struct spdk_json_object_decoder rpc_portal_group_decoders[] = {
723 : : {"tag", offsetof(struct rpc_portal_group, tag), spdk_json_decode_int32},
724 : : {"portals", offsetof(struct rpc_portal_group, portal_list), decode_rpc_portal_list},
725 : : {"private", offsetof(struct rpc_portal_group, is_private), spdk_json_decode_bool, true},
726 : : {"wait", offsetof(struct rpc_portal_group, wait), spdk_json_decode_bool, true},
727 : : };
728 : :
729 : : static void
730 : 52 : rpc_iscsi_create_portal_group(struct spdk_jsonrpc_request *request,
731 : : const struct spdk_json_val *params)
732 : : {
733 : 52 : struct rpc_portal_group req = {};
734 : 52 : struct spdk_iscsi_portal_grp *pg = NULL;
735 : : struct spdk_iscsi_portal *portal;
736 : 52 : size_t i = 0;
737 : 52 : int rc = -1;
738 : :
739 [ - + ]: 52 : if (spdk_json_decode_object(params, rpc_portal_group_decoders,
740 : : SPDK_COUNTOF(rpc_portal_group_decoders),
741 : : &req)) {
742 : 0 : SPDK_ERRLOG("spdk_json_decode_object failed\n");
743 : 0 : goto out;
744 : : }
745 : :
746 [ - + ]: 52 : pg = iscsi_portal_grp_create(req.tag, req.is_private);
747 [ - + ]: 52 : if (pg == NULL) {
748 : 0 : SPDK_ERRLOG("portal_grp_create failed\n");
749 : 0 : goto out;
750 : : }
751 [ + + ]: 106 : for (i = 0; i < req.portal_list.num_portals; i++) {
752 : 54 : portal = iscsi_portal_create(req.portal_list.portals[i].host,
753 : 54 : req.portal_list.portals[i].port);
754 [ - + ]: 54 : if (portal == NULL) {
755 : 0 : SPDK_ERRLOG("portal_create failed\n");
756 : 0 : goto out;
757 : : }
758 : 54 : iscsi_portal_grp_add_portal(pg, portal);
759 : : }
760 : :
761 [ - + ]: 52 : rc = iscsi_portal_grp_open(pg, req.wait);
762 [ - + ]: 52 : if (rc != 0) {
763 : 0 : SPDK_ERRLOG("portal_grp_open failed\n");
764 : 0 : goto out;
765 : : }
766 : :
767 : 52 : rc = iscsi_portal_grp_register(pg);
768 [ + - ]: 52 : if (rc != 0) {
769 : 0 : SPDK_ERRLOG("portal_grp_register failed\n");
770 : : }
771 : :
772 : 52 : out:
773 [ + - ]: 52 : if (rc == 0) {
774 : 52 : spdk_jsonrpc_send_bool_response(request, true);
775 : : } else {
776 : 0 : spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
777 : :
778 [ # # ]: 0 : if (pg != NULL) {
779 : 0 : iscsi_portal_grp_release(pg);
780 : : }
781 : : }
782 : 52 : free_rpc_portal_group(&req);
783 : 52 : }
784 : 588 : SPDK_RPC_REGISTER("iscsi_create_portal_group", rpc_iscsi_create_portal_group, SPDK_RPC_RUNTIME)
785 : :
786 : : struct rpc_iscsi_change_portal_group {
787 : : int32_t tag;
788 : : };
789 : :
790 : : static const struct spdk_json_object_decoder rpc_iscsi_change_portal_group_decoders[] = {
791 : : {"tag", offsetof(struct rpc_iscsi_change_portal_group, tag), spdk_json_decode_int32},
792 : : };
793 : :
794 : : typedef int (*iscsi_change_portal_grp_fn)(int pg_tag);
795 : :
796 : : static void
797 : 16 : _rpc_iscsi_change_portal_group(struct spdk_jsonrpc_request *request,
798 : : const struct spdk_json_val *params,
799 : : iscsi_change_portal_grp_fn fn)
800 : : {
801 : 16 : struct rpc_iscsi_change_portal_group req = {};
802 : : int rc;
803 : :
804 [ - + ]: 16 : if (spdk_json_decode_object(params, rpc_iscsi_change_portal_group_decoders,
805 : : SPDK_COUNTOF(rpc_iscsi_change_portal_group_decoders),
806 : : &req)) {
807 : 0 : SPDK_ERRLOG("spdk_json_decode_object failed\n");
808 : 0 : goto invalid;
809 : : }
810 : :
811 : 16 : rc = fn(req.tag);
812 [ - + ]: 16 : if (rc != 0) {
813 : 0 : goto invalid;
814 : : }
815 : :
816 : 16 : spdk_jsonrpc_send_bool_response(request, true);
817 : 16 : return;
818 : :
819 : 0 : invalid:
820 : 0 : spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
821 : : }
822 : :
823 : : static int
824 : 16 : _rpc_iscsi_delete_portal_group(int pg_tag)
825 : : {
826 : : struct spdk_iscsi_portal_grp *pg;
827 : :
828 : 16 : pg = iscsi_portal_grp_unregister(pg_tag);
829 [ - + ]: 16 : if (!pg) {
830 : 0 : return -ENODEV;
831 : : }
832 : :
833 : 16 : iscsi_tgt_node_delete_map(pg, NULL);
834 : 16 : iscsi_portal_grp_release(pg);
835 : 16 : return 0;
836 : : }
837 : :
838 : : static void
839 : 16 : rpc_iscsi_delete_portal_group(struct spdk_jsonrpc_request *request,
840 : : const struct spdk_json_val *params)
841 : : {
842 : 16 : _rpc_iscsi_change_portal_group(request, params, _rpc_iscsi_delete_portal_group);
843 : 16 : }
844 : 588 : SPDK_RPC_REGISTER("iscsi_delete_portal_group", rpc_iscsi_delete_portal_group, SPDK_RPC_RUNTIME)
845 : :
846 : : static int
847 : 0 : _rpc_iscsi_start_portal_group(int pg_tag)
848 : : {
849 : : struct spdk_iscsi_portal_grp *pg;
850 : :
851 : 0 : pg = iscsi_portal_grp_find_by_tag(pg_tag);
852 [ # # ]: 0 : if (!pg) {
853 : 0 : return -ENODEV;
854 : : }
855 : :
856 : 0 : iscsi_portal_grp_resume(pg);
857 : 0 : return 0;
858 : : }
859 : :
860 : : static void
861 : 0 : rpc_iscsi_start_portal_group(struct spdk_jsonrpc_request *request,
862 : : const struct spdk_json_val *params)
863 : : {
864 : 0 : _rpc_iscsi_change_portal_group(request, params, _rpc_iscsi_start_portal_group);
865 : 0 : }
866 : 588 : SPDK_RPC_REGISTER("iscsi_start_portal_group", rpc_iscsi_start_portal_group, SPDK_RPC_RUNTIME)
867 : :
868 : : struct rpc_portal_group_auth {
869 : : int32_t tag;
870 : : bool disable_chap;
871 : : bool require_chap;
872 : : bool mutual_chap;
873 : : int32_t chap_group;
874 : : };
875 : :
876 : : static const struct spdk_json_object_decoder rpc_portal_group_auth_decoders[] = {
877 : : {"tag", offsetof(struct rpc_portal_group_auth, tag), spdk_json_decode_int32},
878 : : {"disable_chap", offsetof(struct rpc_portal_group_auth, disable_chap), spdk_json_decode_bool, true},
879 : : {"require_chap", offsetof(struct rpc_portal_group_auth, require_chap), spdk_json_decode_bool, true},
880 : : {"mutual_chap", offsetof(struct rpc_portal_group_auth, mutual_chap), spdk_json_decode_bool, true},
881 : : {"chap_group", offsetof(struct rpc_portal_group_auth, chap_group), spdk_json_decode_int32, true},
882 : : };
883 : :
884 : : static void
885 : 0 : rpc_iscsi_portal_group_set_auth(struct spdk_jsonrpc_request *request,
886 : : const struct spdk_json_val *params)
887 : : {
888 : 0 : struct rpc_portal_group_auth req = {};
889 : : struct spdk_iscsi_portal_grp *pg;
890 : : int rc;
891 : :
892 [ # # ]: 0 : if (spdk_json_decode_object(params, rpc_portal_group_auth_decoders,
893 : : SPDK_COUNTOF(rpc_portal_group_auth_decoders), &req)) {
894 : 0 : SPDK_ERRLOG("spdk_json_decode_object failed\n");
895 : 0 : spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
896 : : "Invalid parameters");
897 : 0 : return;
898 : : }
899 : :
900 [ # # ]: 0 : pthread_mutex_lock(&g_iscsi.mutex);
901 : :
902 : 0 : pg = iscsi_portal_grp_find_by_tag(req.tag);
903 [ # # ]: 0 : if (pg == NULL) {
904 : 0 : spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
905 : : "Could not find portal group %d", req.tag);
906 : 0 : goto exit;
907 : : }
908 : :
909 [ # # ]: 0 : rc = iscsi_portal_grp_set_chap_params(pg, req.disable_chap, req.require_chap,
910 [ # # # # ]: 0 : req.mutual_chap, req.chap_group);
911 [ # # ]: 0 : if (rc < 0) {
912 : 0 : spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
913 : : "Invalid combination of auth params");
914 : 0 : goto exit;
915 : : }
916 : :
917 [ # # ]: 0 : pthread_mutex_unlock(&g_iscsi.mutex);
918 : :
919 : 0 : spdk_jsonrpc_send_bool_response(request, true);
920 : 0 : return;
921 : :
922 : 0 : exit:
923 [ # # ]: 0 : pthread_mutex_unlock(&g_iscsi.mutex);
924 : : }
925 : 588 : SPDK_RPC_REGISTER("iscsi_portal_group_set_auth", rpc_iscsi_portal_group_set_auth,
926 : : SPDK_RPC_RUNTIME)
927 : :
928 : : struct rpc_iscsi_get_connections_ctx {
929 : : struct spdk_jsonrpc_request *request;
930 : : struct spdk_json_write_ctx *w;
931 : : };
932 : :
933 : : static void
934 : 136 : _rpc_iscsi_get_connections_done(struct spdk_io_channel_iter *i, int status)
935 : : {
936 : 136 : struct rpc_iscsi_get_connections_ctx *ctx = spdk_io_channel_iter_get_ctx(i);
937 : :
938 : 136 : spdk_json_write_array_end(ctx->w);
939 : 136 : spdk_jsonrpc_end_result(ctx->request, ctx->w);
940 : :
941 : 136 : free(ctx);
942 : 136 : }
943 : :
944 : : static void
945 : 248 : _rpc_iscsi_get_connections(struct spdk_io_channel_iter *i)
946 : : {
947 : 248 : struct rpc_iscsi_get_connections_ctx *ctx = spdk_io_channel_iter_get_ctx(i);
948 : 248 : struct spdk_io_channel *ch = spdk_io_channel_iter_get_channel(i);
949 : 248 : struct spdk_iscsi_poll_group *pg = spdk_io_channel_get_ctx(ch);
950 : : struct spdk_iscsi_conn *conn;
951 : :
952 [ + + ]: 256 : STAILQ_FOREACH(conn, &pg->connections, pg_link) {
953 : 8 : iscsi_conn_info_json(ctx->w, conn);
954 : : }
955 : :
956 : 248 : spdk_for_each_channel_continue(i, 0);
957 : 248 : }
958 : :
959 : : static void
960 : 136 : rpc_iscsi_get_connections(struct spdk_jsonrpc_request *request,
961 : : const struct spdk_json_val *params)
962 : : {
963 : : struct rpc_iscsi_get_connections_ctx *ctx;
964 : :
965 [ - + ]: 136 : if (params != NULL) {
966 : 0 : spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
967 : : "iscsi_get_connections requires no parameters");
968 : 0 : return;
969 : : }
970 : :
971 : 136 : ctx = calloc(1, sizeof(struct rpc_iscsi_get_connections_ctx));
972 [ - + ]: 136 : if (ctx == NULL) {
973 : 0 : SPDK_ERRLOG("Failed to allocate rpc_get_iscsi_conns_ctx struct\n");
974 : 0 : spdk_jsonrpc_send_error_response(request, -ENOMEM, spdk_strerror(ENOMEM));
975 : 0 : return;
976 : : }
977 : :
978 : 136 : ctx->request = request;
979 : 136 : ctx->w = spdk_jsonrpc_begin_result(request);
980 : :
981 : 136 : spdk_json_write_array_begin(ctx->w);
982 : :
983 : 136 : spdk_for_each_channel(&g_iscsi,
984 : : _rpc_iscsi_get_connections,
985 : : ctx,
986 : : _rpc_iscsi_get_connections_done);
987 : : }
988 : 588 : SPDK_RPC_REGISTER("iscsi_get_connections", rpc_iscsi_get_connections, SPDK_RPC_RUNTIME)
989 : :
990 : : struct rpc_target_lun {
991 : : char *name;
992 : : char *bdev_name;
993 : : int32_t lun_id;
994 : : };
995 : :
996 : : static void
997 : 4 : free_rpc_target_lun(struct rpc_target_lun *req)
998 : : {
999 : 4 : free(req->name);
1000 : 4 : free(req->bdev_name);
1001 : 4 : }
1002 : :
1003 : : static const struct spdk_json_object_decoder rpc_target_lun_decoders[] = {
1004 : : {"name", offsetof(struct rpc_target_lun, name), spdk_json_decode_string},
1005 : : {"bdev_name", offsetof(struct rpc_target_lun, bdev_name), spdk_json_decode_string},
1006 : : {"lun_id", offsetof(struct rpc_target_lun, lun_id), spdk_json_decode_int32, true},
1007 : : };
1008 : :
1009 : : static void
1010 : 4 : rpc_iscsi_target_node_add_lun(struct spdk_jsonrpc_request *request,
1011 : : const struct spdk_json_val *params)
1012 : : {
1013 : 4 : struct rpc_target_lun req = {};
1014 : : struct spdk_iscsi_tgt_node *target;
1015 : : int rc;
1016 : :
1017 : 4 : req.lun_id = -1;
1018 : :
1019 [ - + ]: 4 : if (spdk_json_decode_object(params, rpc_target_lun_decoders,
1020 : : SPDK_COUNTOF(rpc_target_lun_decoders), &req)) {
1021 : 0 : SPDK_ERRLOG("spdk_json_decode_object failed\n");
1022 : 0 : goto invalid;
1023 : : }
1024 : :
1025 : 4 : target = iscsi_find_tgt_node(req.name);
1026 [ - + ]: 4 : if (target == NULL) {
1027 : 0 : SPDK_ERRLOG("target is not found\n");
1028 : 0 : goto invalid;
1029 : : }
1030 : :
1031 : 4 : rc = iscsi_tgt_node_add_lun(target, req.bdev_name, req.lun_id);
1032 [ - + ]: 4 : if (rc < 0) {
1033 : 0 : SPDK_ERRLOG("add lun failed\n");
1034 : 0 : goto invalid;
1035 : : }
1036 : :
1037 : 4 : free_rpc_target_lun(&req);
1038 : :
1039 : 4 : spdk_jsonrpc_send_bool_response(request, true);
1040 : 4 : return;
1041 : :
1042 : 0 : invalid:
1043 : 0 : spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
1044 : : "Invalid parameters");
1045 : 0 : free_rpc_target_lun(&req);
1046 : : }
1047 : 588 : SPDK_RPC_REGISTER("iscsi_target_node_add_lun", rpc_iscsi_target_node_add_lun, SPDK_RPC_RUNTIME)
1048 : :
1049 : : struct rpc_target_auth {
1050 : : char *name;
1051 : : bool disable_chap;
1052 : : bool require_chap;
1053 : : bool mutual_chap;
1054 : : int32_t chap_group;
1055 : : };
1056 : :
1057 : : static void
1058 : 2 : free_rpc_target_auth(struct rpc_target_auth *req)
1059 : : {
1060 : 2 : free(req->name);
1061 : 2 : }
1062 : :
1063 : : static const struct spdk_json_object_decoder rpc_target_auth_decoders[] = {
1064 : : {"name", offsetof(struct rpc_target_auth, name), spdk_json_decode_string},
1065 : : {"disable_chap", offsetof(struct rpc_target_auth, disable_chap), spdk_json_decode_bool, true},
1066 : : {"require_chap", offsetof(struct rpc_target_auth, require_chap), spdk_json_decode_bool, true},
1067 : : {"mutual_chap", offsetof(struct rpc_target_auth, mutual_chap), spdk_json_decode_bool, true},
1068 : : {"chap_group", offsetof(struct rpc_target_auth, chap_group), spdk_json_decode_int32, true},
1069 : : };
1070 : :
1071 : : static void
1072 : 2 : rpc_iscsi_target_node_set_auth(struct spdk_jsonrpc_request *request,
1073 : : const struct spdk_json_val *params)
1074 : : {
1075 : 2 : struct rpc_target_auth req = {};
1076 : : struct spdk_iscsi_tgt_node *target;
1077 : : int rc;
1078 : :
1079 [ - + ]: 2 : if (spdk_json_decode_object(params, rpc_target_auth_decoders,
1080 : : SPDK_COUNTOF(rpc_target_auth_decoders), &req)) {
1081 : 0 : SPDK_ERRLOG("spdk_json_decode_object failed\n");
1082 : 0 : spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
1083 : : "Invalid parameters");
1084 : 0 : goto exit;
1085 : : }
1086 : :
1087 : 2 : target = iscsi_find_tgt_node(req.name);
1088 [ - + ]: 2 : if (target == NULL) {
1089 : 0 : spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
1090 : : "Could not find target %s", req.name);
1091 : 0 : goto exit;
1092 : : }
1093 : :
1094 [ - + ]: 2 : rc = iscsi_tgt_node_set_chap_params(target, req.disable_chap, req.require_chap,
1095 [ - + - + ]: 2 : req.mutual_chap, req.chap_group);
1096 [ - + ]: 2 : if (rc < 0) {
1097 : 0 : spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
1098 : : "Invalid combination of auth params");
1099 : 0 : goto exit;
1100 : : }
1101 : :
1102 : 2 : free_rpc_target_auth(&req);
1103 : :
1104 : 2 : spdk_jsonrpc_send_bool_response(request, true);
1105 : 2 : return;
1106 : :
1107 : 0 : exit:
1108 : 0 : free_rpc_target_auth(&req);
1109 : : }
1110 : 588 : SPDK_RPC_REGISTER("iscsi_target_node_set_auth", rpc_iscsi_target_node_set_auth,
1111 : : SPDK_RPC_RUNTIME)
1112 : :
1113 : : struct rpc_target_redirect {
1114 : : char *name;
1115 : : int32_t pg_tag;
1116 : : char *redirect_host;
1117 : : char *redirect_port;
1118 : : };
1119 : :
1120 : : static void
1121 : 4 : free_rpc_target_redirect(struct rpc_target_redirect *req)
1122 : : {
1123 : 4 : free(req->name);
1124 : 4 : free(req->redirect_host);
1125 : 4 : free(req->redirect_port);
1126 : 4 : }
1127 : :
1128 : : static const struct spdk_json_object_decoder rpc_target_redirect_decoders[] = {
1129 : : {"name", offsetof(struct rpc_target_redirect, name), spdk_json_decode_string},
1130 : : {"pg_tag", offsetof(struct rpc_target_redirect, pg_tag), spdk_json_decode_int32},
1131 : : {"redirect_host", offsetof(struct rpc_target_redirect, redirect_host), spdk_json_decode_string, true},
1132 : : {"redirect_port", offsetof(struct rpc_target_redirect, redirect_port), spdk_json_decode_string, true},
1133 : : };
1134 : :
1135 : : static void
1136 : 4 : rpc_iscsi_target_node_set_redirect(struct spdk_jsonrpc_request *request,
1137 : : const struct spdk_json_val *params)
1138 : : {
1139 : 4 : struct rpc_target_redirect req = {};
1140 : : struct spdk_iscsi_tgt_node *target;
1141 : : int rc;
1142 : :
1143 [ - + ]: 4 : if (spdk_json_decode_object(params, rpc_target_redirect_decoders,
1144 : : SPDK_COUNTOF(rpc_target_redirect_decoders),
1145 : : &req)) {
1146 : 0 : SPDK_ERRLOG("spdk_json_decode_object failed\n");
1147 : 0 : spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
1148 : : "Invalid parameters");
1149 : 0 : free_rpc_target_redirect(&req);
1150 : 0 : return;
1151 : : }
1152 : :
1153 : 4 : target = iscsi_find_tgt_node(req.name);
1154 [ - + ]: 4 : if (target == NULL) {
1155 : 0 : SPDK_ERRLOG("target %s is not found\n", req.name);
1156 : 0 : spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
1157 : : "Target %s is not found", req.name);
1158 : 0 : free_rpc_target_redirect(&req);
1159 : 0 : return;
1160 : : }
1161 : :
1162 : 4 : rc = iscsi_tgt_node_redirect(target, req.pg_tag, req.redirect_host, req.redirect_port);
1163 [ - + ]: 4 : if (rc != 0) {
1164 : 0 : SPDK_ERRLOG("failed to redirect target %s\n", req.name);
1165 : 0 : spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
1166 : : "Failed to redirect target %s, (%d): %s",
1167 : : req.name, rc, spdk_strerror(-rc));
1168 : 0 : free_rpc_target_redirect(&req);
1169 : 0 : return;
1170 : : }
1171 : :
1172 : 4 : free_rpc_target_redirect(&req);
1173 : :
1174 : 4 : spdk_jsonrpc_send_bool_response(request, true);
1175 : : }
1176 : 588 : SPDK_RPC_REGISTER("iscsi_target_node_set_redirect", rpc_iscsi_target_node_set_redirect,
1177 : : SPDK_RPC_RUNTIME)
1178 : :
1179 : : struct rpc_target_logout {
1180 : : char *name;
1181 : : int32_t pg_tag;
1182 : : };
1183 : :
1184 : : static void
1185 : 4 : free_rpc_target_logout(struct rpc_target_logout *req)
1186 : : {
1187 : 4 : free(req->name);
1188 : 4 : }
1189 : :
1190 : : static const struct spdk_json_object_decoder rpc_target_logout_decoders[] = {
1191 : : {"name", offsetof(struct rpc_target_logout, name), spdk_json_decode_string},
1192 : : {"pg_tag", offsetof(struct rpc_target_logout, pg_tag), spdk_json_decode_int32, true},
1193 : : };
1194 : :
1195 : : static void
1196 : 4 : rpc_iscsi_target_node_request_logout(struct spdk_jsonrpc_request *request,
1197 : : const struct spdk_json_val *params)
1198 : : {
1199 : 4 : struct rpc_target_logout req = {};
1200 : : struct spdk_iscsi_tgt_node *target;
1201 : :
1202 : : /* If pg_tag is omitted, request all connections to the specified target
1203 : : * to logout.
1204 : : */
1205 : 4 : req.pg_tag = -1;
1206 : :
1207 [ - + ]: 4 : if (spdk_json_decode_object(params, rpc_target_logout_decoders,
1208 : : SPDK_COUNTOF(rpc_target_logout_decoders),
1209 : : &req)) {
1210 : 0 : SPDK_ERRLOG("spdk_json_decode_object failed\n");
1211 : 0 : spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
1212 : : "Invalid parameters");
1213 : 0 : free_rpc_target_logout(&req);
1214 : 0 : return;
1215 : : }
1216 : :
1217 : 4 : target = iscsi_find_tgt_node(req.name);
1218 [ - + ]: 4 : if (target == NULL) {
1219 : 0 : SPDK_ERRLOG("target %s is not found\n", req.name);
1220 : 0 : spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
1221 : : "Target %s is not found", req.name);
1222 : 0 : free_rpc_target_logout(&req);
1223 : 0 : return;
1224 : : }
1225 : :
1226 : 4 : iscsi_conns_request_logout(target, req.pg_tag);
1227 : :
1228 : 4 : free_rpc_target_logout(&req);
1229 : :
1230 : 4 : spdk_jsonrpc_send_bool_response(request, true);
1231 : : }
1232 : 588 : SPDK_RPC_REGISTER("iscsi_target_node_request_logout", rpc_iscsi_target_node_request_logout,
1233 : : SPDK_RPC_RUNTIME)
1234 : :
1235 : : static void
1236 : 124 : rpc_iscsi_get_options(struct spdk_jsonrpc_request *request,
1237 : : const struct spdk_json_val *params)
1238 : : {
1239 : : struct spdk_json_write_ctx *w;
1240 : :
1241 [ - + ]: 124 : if (params != NULL) {
1242 : 0 : spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
1243 : : "iscsi_get_options requires no parameters");
1244 : 0 : return;
1245 : : }
1246 : :
1247 : 124 : w = spdk_jsonrpc_begin_result(request);
1248 : 124 : iscsi_opts_info_json(w);
1249 : :
1250 : 124 : spdk_jsonrpc_end_result(request, w);
1251 : : }
1252 : 588 : SPDK_RPC_REGISTER("iscsi_get_options", rpc_iscsi_get_options, SPDK_RPC_RUNTIME)
1253 : :
1254 : : struct rpc_discovery_auth {
1255 : : bool disable_chap;
1256 : : bool require_chap;
1257 : : bool mutual_chap;
1258 : : int32_t chap_group;
1259 : : };
1260 : :
1261 : : static const struct spdk_json_object_decoder rpc_discovery_auth_decoders[] = {
1262 : : {"disable_chap", offsetof(struct rpc_discovery_auth, disable_chap), spdk_json_decode_bool, true},
1263 : : {"require_chap", offsetof(struct rpc_discovery_auth, require_chap), spdk_json_decode_bool, true},
1264 : : {"mutual_chap", offsetof(struct rpc_discovery_auth, mutual_chap), spdk_json_decode_bool, true},
1265 : : {"chap_group", offsetof(struct rpc_discovery_auth, chap_group), spdk_json_decode_int32, true},
1266 : : };
1267 : :
1268 : : static void
1269 : 4 : rpc_iscsi_set_discovery_auth(struct spdk_jsonrpc_request *request,
1270 : : const struct spdk_json_val *params)
1271 : : {
1272 : 4 : struct rpc_discovery_auth req = {};
1273 : : int rc;
1274 : :
1275 [ - + ]: 4 : if (spdk_json_decode_object(params, rpc_discovery_auth_decoders,
1276 : : SPDK_COUNTOF(rpc_discovery_auth_decoders), &req)) {
1277 : 0 : SPDK_ERRLOG("spdk_json_decode_object failed\n");
1278 : 0 : spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
1279 : : "Invalid parameters");
1280 : 0 : return;
1281 : : }
1282 : :
1283 [ - + ]: 4 : rc = iscsi_set_discovery_auth(req.disable_chap, req.require_chap,
1284 [ - + - + ]: 4 : req.mutual_chap, req.chap_group);
1285 [ - + ]: 4 : if (rc < 0) {
1286 : 0 : spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
1287 : : "Invalid combination of CHAP params");
1288 : 0 : return;
1289 : : }
1290 : :
1291 : 4 : spdk_jsonrpc_send_bool_response(request, true);
1292 : : }
1293 : 588 : SPDK_RPC_REGISTER("iscsi_set_discovery_auth", rpc_iscsi_set_discovery_auth, SPDK_RPC_RUNTIME)
1294 : :
1295 : : #define MAX_AUTH_SECRETS 64
1296 : :
1297 : : struct rpc_auth_secret {
1298 : : char *user;
1299 : : char *secret;
1300 : : char *muser;
1301 : : char *msecret;
1302 : : };
1303 : :
1304 : : static void
1305 : 8 : free_rpc_auth_secret(struct rpc_auth_secret *_secret)
1306 : : {
1307 : 8 : free(_secret->user);
1308 : 8 : free(_secret->secret);
1309 : 8 : free(_secret->muser);
1310 : 8 : free(_secret->msecret);
1311 : 8 : }
1312 : :
1313 : : static const struct spdk_json_object_decoder rpc_auth_secret_decoders[] = {
1314 : : {"user", offsetof(struct rpc_auth_secret, user), spdk_json_decode_string},
1315 : : {"secret", offsetof(struct rpc_auth_secret, secret), spdk_json_decode_string},
1316 : : {"muser", offsetof(struct rpc_auth_secret, muser), spdk_json_decode_string, true},
1317 : : {"msecret", offsetof(struct rpc_auth_secret, msecret), spdk_json_decode_string, true},
1318 : : };
1319 : :
1320 : : static int
1321 : 8 : decode_rpc_auth_secret(const struct spdk_json_val *val, void *out)
1322 : : {
1323 : 8 : struct rpc_auth_secret *_secret = out;
1324 : :
1325 : 8 : return spdk_json_decode_object(val, rpc_auth_secret_decoders,
1326 : : SPDK_COUNTOF(rpc_auth_secret_decoders), _secret);
1327 : : }
1328 : :
1329 : : struct rpc_auth_secrets {
1330 : : size_t num_secret;
1331 : : struct rpc_auth_secret secrets[MAX_AUTH_SECRETS];
1332 : : };
1333 : :
1334 : : static void
1335 : 6 : free_rpc_auth_secrets(struct rpc_auth_secrets *secrets)
1336 : : {
1337 : : size_t i;
1338 : :
1339 [ + + ]: 14 : for (i = 0; i < secrets->num_secret; i++) {
1340 : 8 : free_rpc_auth_secret(&secrets->secrets[i]);
1341 : : }
1342 : 6 : }
1343 : :
1344 : : static int
1345 : 6 : decode_rpc_auth_secrets(const struct spdk_json_val *val, void *out)
1346 : : {
1347 : 6 : struct rpc_auth_secrets *secrets = out;
1348 : :
1349 : 6 : return spdk_json_decode_array(val, decode_rpc_auth_secret, secrets->secrets,
1350 : : MAX_AUTH_SECRETS, &secrets->num_secret,
1351 : : sizeof(struct rpc_auth_secret));
1352 : : }
1353 : :
1354 : : struct rpc_auth_group {
1355 : : int32_t tag;
1356 : : struct rpc_auth_secrets secrets;
1357 : : };
1358 : :
1359 : : static void
1360 : 6 : free_rpc_auth_group(struct rpc_auth_group *group)
1361 : : {
1362 : 6 : free_rpc_auth_secrets(&group->secrets);
1363 : 6 : }
1364 : :
1365 : : static const struct spdk_json_object_decoder rpc_auth_group_decoders[] = {
1366 : : {"tag", offsetof(struct rpc_auth_group, tag), spdk_json_decode_int32},
1367 : : {"secrets", offsetof(struct rpc_auth_group, secrets), decode_rpc_auth_secrets, true},
1368 : : };
1369 : :
1370 : : static void
1371 : 6 : rpc_iscsi_create_auth_group(struct spdk_jsonrpc_request *request,
1372 : : const struct spdk_json_val *params)
1373 : : {
1374 : 6 : struct rpc_auth_group req = {};
1375 : : struct rpc_auth_secret *_secret;
1376 : 6 : struct spdk_iscsi_auth_group *group = NULL;
1377 : : int rc;
1378 : : size_t i;
1379 : :
1380 [ - + ]: 6 : if (spdk_json_decode_object(params, rpc_auth_group_decoders,
1381 : : SPDK_COUNTOF(rpc_auth_group_decoders), &req)) {
1382 : 0 : SPDK_ERRLOG("spdk_json_decode_object failed\n");
1383 : 0 : spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
1384 : : "Invalid parameters");
1385 : 0 : free_rpc_auth_group(&req);
1386 : 0 : return;
1387 : : }
1388 : :
1389 [ - + ]: 6 : pthread_mutex_lock(&g_iscsi.mutex);
1390 : :
1391 : 6 : rc = iscsi_add_auth_group(req.tag, &group);
1392 [ - + ]: 6 : if (rc != 0) {
1393 [ # # ]: 0 : pthread_mutex_unlock(&g_iscsi.mutex);
1394 : :
1395 : 0 : spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
1396 : : "Could not add auth group (%d), %s",
1397 : : req.tag, spdk_strerror(-rc));
1398 : 0 : free_rpc_auth_group(&req);
1399 : 0 : return;
1400 : : }
1401 : :
1402 [ + + ]: 14 : for (i = 0; i < req.secrets.num_secret; i++) {
1403 : 8 : _secret = &req.secrets.secrets[i];
1404 : 8 : rc = iscsi_auth_group_add_secret(group, _secret->user, _secret->secret,
1405 : 8 : _secret->muser, _secret->msecret);
1406 [ - + ]: 8 : if (rc != 0) {
1407 : 0 : iscsi_delete_auth_group(group);
1408 [ # # ]: 0 : pthread_mutex_unlock(&g_iscsi.mutex);
1409 : :
1410 : 0 : spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
1411 : : "Could not add secret to auth group (%d), %s",
1412 : : req.tag, spdk_strerror(-rc));
1413 : 0 : free_rpc_auth_group(&req);
1414 : 0 : return;
1415 : : }
1416 : : }
1417 : :
1418 [ - + ]: 6 : pthread_mutex_unlock(&g_iscsi.mutex);
1419 : :
1420 : 6 : free_rpc_auth_group(&req);
1421 : :
1422 : 6 : spdk_jsonrpc_send_bool_response(request, true);
1423 : : }
1424 : 588 : SPDK_RPC_REGISTER("iscsi_create_auth_group", rpc_iscsi_create_auth_group, SPDK_RPC_RUNTIME)
1425 : :
1426 : : struct rpc_delete_auth_group {
1427 : : int32_t tag;
1428 : : };
1429 : :
1430 : : static const struct spdk_json_object_decoder rpc_delete_auth_group_decoders[] = {
1431 : : {"tag", offsetof(struct rpc_delete_auth_group, tag), spdk_json_decode_int32},
1432 : : };
1433 : :
1434 : : static void
1435 : 4 : rpc_iscsi_delete_auth_group(struct spdk_jsonrpc_request *request,
1436 : : const struct spdk_json_val *params)
1437 : : {
1438 : 4 : struct rpc_delete_auth_group req = {};
1439 : : struct spdk_iscsi_auth_group *group;
1440 : :
1441 [ - + ]: 4 : if (spdk_json_decode_object(params, rpc_delete_auth_group_decoders,
1442 : : SPDK_COUNTOF(rpc_delete_auth_group_decoders), &req)) {
1443 : 0 : SPDK_ERRLOG("spdk_json_decode_object failed\n");
1444 : 0 : spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
1445 : : "Invalid parameters");
1446 : 0 : return;
1447 : : }
1448 : :
1449 [ - + ]: 4 : pthread_mutex_lock(&g_iscsi.mutex);
1450 : :
1451 : 4 : group = iscsi_find_auth_group_by_tag(req.tag);
1452 [ - + ]: 4 : if (group == NULL) {
1453 [ # # ]: 0 : pthread_mutex_unlock(&g_iscsi.mutex);
1454 : :
1455 : 0 : spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
1456 : : "Could not find auth group (%d)", req.tag);
1457 : 0 : return;
1458 : : }
1459 : :
1460 : 4 : iscsi_delete_auth_group(group);
1461 : :
1462 [ - + ]: 4 : pthread_mutex_unlock(&g_iscsi.mutex);
1463 : :
1464 : 4 : spdk_jsonrpc_send_bool_response(request, true);
1465 : : }
1466 : 588 : SPDK_RPC_REGISTER("iscsi_delete_auth_group", rpc_iscsi_delete_auth_group, SPDK_RPC_RUNTIME)
1467 : :
1468 : : struct rpc_add_auth_secret {
1469 : : int32_t tag;
1470 : : char *user;
1471 : : char *secret;
1472 : : char *muser;
1473 : : char *msecret;
1474 : : };
1475 : :
1476 : : static void
1477 : 2 : free_rpc_add_auth_secret(struct rpc_add_auth_secret *_secret)
1478 : : {
1479 : 2 : free(_secret->user);
1480 : 2 : free(_secret->secret);
1481 : 2 : free(_secret->muser);
1482 : 2 : free(_secret->msecret);
1483 : 2 : }
1484 : :
1485 : : static const struct spdk_json_object_decoder rpc_add_auth_secret_decoders[] = {
1486 : : {"tag", offsetof(struct rpc_add_auth_secret, tag), spdk_json_decode_int32},
1487 : : {"user", offsetof(struct rpc_add_auth_secret, user), spdk_json_decode_string},
1488 : : {"secret", offsetof(struct rpc_add_auth_secret, secret), spdk_json_decode_string},
1489 : : {"muser", offsetof(struct rpc_add_auth_secret, muser), spdk_json_decode_string, true},
1490 : : {"msecret", offsetof(struct rpc_add_auth_secret, msecret), spdk_json_decode_string, true},
1491 : : };
1492 : :
1493 : : static void
1494 : 2 : rpc_iscsi_auth_group_add_secret(struct spdk_jsonrpc_request *request,
1495 : : const struct spdk_json_val *params)
1496 : : {
1497 : 2 : struct rpc_add_auth_secret req = {};
1498 : : struct spdk_iscsi_auth_group *group;
1499 : : int rc;
1500 : :
1501 [ - + ]: 2 : if (spdk_json_decode_object(params, rpc_add_auth_secret_decoders,
1502 : : SPDK_COUNTOF(rpc_add_auth_secret_decoders), &req)) {
1503 : 0 : SPDK_ERRLOG("spdk_json_decode_object failed\n");
1504 : 0 : spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
1505 : : "Invalid parameters");
1506 : 0 : free_rpc_add_auth_secret(&req);
1507 : 0 : return;
1508 : : }
1509 : :
1510 [ - + ]: 2 : pthread_mutex_lock(&g_iscsi.mutex);
1511 : :
1512 : 2 : group = iscsi_find_auth_group_by_tag(req.tag);
1513 [ - + ]: 2 : if (group == NULL) {
1514 [ # # ]: 0 : pthread_mutex_unlock(&g_iscsi.mutex);
1515 : :
1516 : 0 : spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
1517 : : "Could not find auth group (%d)", req.tag);
1518 : 0 : free_rpc_add_auth_secret(&req);
1519 : 0 : return;
1520 : : }
1521 : :
1522 : 2 : rc = iscsi_auth_group_add_secret(group, req.user, req.secret, req.muser, req.msecret);
1523 [ - + ]: 2 : if (rc != 0) {
1524 [ # # ]: 0 : pthread_mutex_unlock(&g_iscsi.mutex);
1525 : :
1526 : 0 : spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
1527 : : "Could not add secret to auth group (%d), %s",
1528 : : req.tag, spdk_strerror(-rc));
1529 : 0 : free_rpc_add_auth_secret(&req);
1530 : 0 : return;
1531 : : }
1532 : :
1533 [ - + ]: 2 : pthread_mutex_unlock(&g_iscsi.mutex);
1534 : :
1535 : 2 : free_rpc_add_auth_secret(&req);
1536 : :
1537 : 2 : spdk_jsonrpc_send_bool_response(request, true);
1538 : : }
1539 : 588 : SPDK_RPC_REGISTER("iscsi_auth_group_add_secret", rpc_iscsi_auth_group_add_secret,
1540 : : SPDK_RPC_RUNTIME)
1541 : :
1542 : :
1543 : : struct rpc_remove_auth_secret {
1544 : : int32_t tag;
1545 : : char *user;
1546 : : };
1547 : :
1548 : : static void
1549 : 6 : free_rpc_remove_auth_secret(struct rpc_remove_auth_secret *_secret)
1550 : : {
1551 : 6 : free(_secret->user);
1552 : 6 : }
1553 : :
1554 : : static const struct spdk_json_object_decoder rpc_remove_auth_secret_decoders[] = {
1555 : : {"tag", offsetof(struct rpc_remove_auth_secret, tag), spdk_json_decode_int32},
1556 : : {"user", offsetof(struct rpc_remove_auth_secret, user), spdk_json_decode_string},
1557 : : };
1558 : :
1559 : : static void
1560 : 6 : rpc_iscsi_auth_group_remove_secret(struct spdk_jsonrpc_request *request,
1561 : : const struct spdk_json_val *params)
1562 : : {
1563 : 6 : struct rpc_remove_auth_secret req = {};
1564 : : struct spdk_iscsi_auth_group *group;
1565 : : int rc;
1566 : :
1567 [ - + ]: 6 : if (spdk_json_decode_object(params, rpc_remove_auth_secret_decoders,
1568 : : SPDK_COUNTOF(rpc_remove_auth_secret_decoders), &req)) {
1569 : 0 : SPDK_ERRLOG("spdk_json_decode_object failed\n");
1570 : 0 : spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
1571 : : "Invalid parameters");
1572 : 0 : free_rpc_remove_auth_secret(&req);
1573 : 0 : return;
1574 : : }
1575 : :
1576 [ - + ]: 6 : pthread_mutex_lock(&g_iscsi.mutex);
1577 : :
1578 : 6 : group = iscsi_find_auth_group_by_tag(req.tag);
1579 [ - + ]: 6 : if (group == NULL) {
1580 [ # # ]: 0 : pthread_mutex_unlock(&g_iscsi.mutex);
1581 : :
1582 : 0 : spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
1583 : : "Could not find auth group (%d)", req.tag);
1584 : 0 : free_rpc_remove_auth_secret(&req);
1585 : 0 : return;
1586 : : }
1587 : :
1588 : 6 : rc = iscsi_auth_group_delete_secret(group, req.user);
1589 [ - + ]: 6 : if (rc != 0) {
1590 [ # # ]: 0 : pthread_mutex_unlock(&g_iscsi.mutex);
1591 : :
1592 : 0 : spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
1593 : : "Could not delete secret from CHAP group (%d), %s",
1594 : : req.tag, spdk_strerror(-rc));
1595 : 0 : free_rpc_remove_auth_secret(&req);
1596 : 0 : return;
1597 : : }
1598 : :
1599 [ - + ]: 6 : pthread_mutex_unlock(&g_iscsi.mutex);
1600 : :
1601 : 6 : free_rpc_remove_auth_secret(&req);
1602 : :
1603 : 6 : spdk_jsonrpc_send_bool_response(request, true);
1604 : : }
1605 : 588 : SPDK_RPC_REGISTER("iscsi_auth_group_remove_secret",
1606 : : rpc_iscsi_auth_group_remove_secret, SPDK_RPC_RUNTIME)
1607 : :
1608 : : static void
1609 : 132 : rpc_iscsi_get_auth_groups(struct spdk_jsonrpc_request *request,
1610 : : const struct spdk_json_val *params)
1611 : : {
1612 : : struct spdk_json_write_ctx *w;
1613 : :
1614 [ - + ]: 132 : if (params != NULL) {
1615 : 0 : spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
1616 : : "iscsi_get_auth_groups requires no parameters");
1617 : 0 : return;
1618 : : }
1619 : :
1620 : 132 : w = spdk_jsonrpc_begin_result(request);
1621 : 132 : spdk_json_write_array_begin(w);
1622 : 132 : iscsi_auth_groups_info_json(w);
1623 : 132 : spdk_json_write_array_end(w);
1624 : :
1625 : 132 : spdk_jsonrpc_end_result(request, w);
1626 : : }
1627 : 588 : SPDK_RPC_REGISTER("iscsi_get_auth_groups", rpc_iscsi_get_auth_groups, SPDK_RPC_RUNTIME)
1628 : :
1629 : : static const struct spdk_json_object_decoder rpc_set_iscsi_opts_decoders[] = {
1630 : : {"auth_file", offsetof(struct spdk_iscsi_opts, authfile), spdk_json_decode_string, true},
1631 : : {"node_base", offsetof(struct spdk_iscsi_opts, nodebase), spdk_json_decode_string, true},
1632 : : {"nop_timeout", offsetof(struct spdk_iscsi_opts, timeout), spdk_json_decode_int32, true},
1633 : : {"nop_in_interval", offsetof(struct spdk_iscsi_opts, nopininterval), spdk_json_decode_int32, true},
1634 : : {"no_discovery_auth", offsetof(struct spdk_iscsi_opts, disable_chap), spdk_json_decode_bool, true},
1635 : : {"req_discovery_auth", offsetof(struct spdk_iscsi_opts, require_chap), spdk_json_decode_bool, true},
1636 : : {"req_discovery_auth_mutual", offsetof(struct spdk_iscsi_opts, mutual_chap), spdk_json_decode_bool, true},
1637 : : {"discovery_auth_group", offsetof(struct spdk_iscsi_opts, chap_group), spdk_json_decode_int32, true},
1638 : : {"disable_chap", offsetof(struct spdk_iscsi_opts, disable_chap), spdk_json_decode_bool, true},
1639 : : {"require_chap", offsetof(struct spdk_iscsi_opts, require_chap), spdk_json_decode_bool, true},
1640 : : {"mutual_chap", offsetof(struct spdk_iscsi_opts, mutual_chap), spdk_json_decode_bool, true},
1641 : : {"chap_group", offsetof(struct spdk_iscsi_opts, chap_group), spdk_json_decode_int32, true},
1642 : : {"max_sessions", offsetof(struct spdk_iscsi_opts, MaxSessions), spdk_json_decode_uint32, true},
1643 : : {"max_queue_depth", offsetof(struct spdk_iscsi_opts, MaxQueueDepth), spdk_json_decode_uint32, true},
1644 : : {"max_connections_per_session", offsetof(struct spdk_iscsi_opts, MaxConnectionsPerSession), spdk_json_decode_uint32, true},
1645 : : {"default_time2wait", offsetof(struct spdk_iscsi_opts, DefaultTime2Wait), spdk_json_decode_uint32, true},
1646 : : {"default_time2retain", offsetof(struct spdk_iscsi_opts, DefaultTime2Retain), spdk_json_decode_uint32, true},
1647 : : {"first_burst_length", offsetof(struct spdk_iscsi_opts, FirstBurstLength), spdk_json_decode_uint32, true},
1648 : : {"immediate_data", offsetof(struct spdk_iscsi_opts, ImmediateData), spdk_json_decode_bool, true},
1649 : : {"error_recovery_level", offsetof(struct spdk_iscsi_opts, ErrorRecoveryLevel), spdk_json_decode_uint32, true},
1650 : : {"allow_duplicated_isid", offsetof(struct spdk_iscsi_opts, AllowDuplicateIsid), spdk_json_decode_bool, true},
1651 : : {"max_large_datain_per_connection", offsetof(struct spdk_iscsi_opts, MaxLargeDataInPerConnection), spdk_json_decode_uint32, true},
1652 : : {"max_r2t_per_connection", offsetof(struct spdk_iscsi_opts, MaxR2TPerConnection), spdk_json_decode_uint32, true},
1653 : : {"pdu_pool_size", offsetof(struct spdk_iscsi_opts, pdu_pool_size), spdk_json_decode_uint32, true},
1654 : : {"immediate_data_pool_size", offsetof(struct spdk_iscsi_opts, immediate_data_pool_size), spdk_json_decode_uint32, true},
1655 : : {"data_out_pool_size", offsetof(struct spdk_iscsi_opts, data_out_pool_size), spdk_json_decode_uint32, true},
1656 : : };
1657 : :
1658 : : static void
1659 : 48 : rpc_iscsi_set_options(struct spdk_jsonrpc_request *request,
1660 : : const struct spdk_json_val *params)
1661 : : {
1662 : : struct spdk_iscsi_opts *opts;
1663 : :
1664 [ - + ]: 48 : if (g_spdk_iscsi_opts != NULL) {
1665 : 0 : SPDK_ERRLOG("this RPC must not be called more than once.\n");
1666 : 0 : spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
1667 : : "Must not call more than once");
1668 : 0 : return;
1669 : : }
1670 : :
1671 : 48 : opts = iscsi_opts_alloc();
1672 [ - + ]: 48 : if (opts == NULL) {
1673 : 0 : SPDK_ERRLOG("iscsi_opts_alloc() failed.\n");
1674 : 0 : spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
1675 : : "Out of memory");
1676 : 0 : return;
1677 : : }
1678 : :
1679 [ + - ]: 48 : if (params != NULL) {
1680 [ - + ]: 48 : if (spdk_json_decode_object(params, rpc_set_iscsi_opts_decoders,
1681 : : SPDK_COUNTOF(rpc_set_iscsi_opts_decoders), opts)) {
1682 : 0 : SPDK_ERRLOG("spdk_json_decode_object() failed\n");
1683 : 0 : spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
1684 : : "Invalid parameters");
1685 : 0 : iscsi_opts_free(opts);
1686 : 0 : return;
1687 : : }
1688 : : }
1689 : :
1690 : 48 : g_spdk_iscsi_opts = iscsi_opts_copy(opts);
1691 : 48 : iscsi_opts_free(opts);
1692 : :
1693 [ - + ]: 48 : if (g_spdk_iscsi_opts == NULL) {
1694 : 0 : SPDK_ERRLOG("iscsi_opts_copy() failed\n");
1695 : 0 : spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
1696 : : "Out of memory");
1697 : 0 : return;
1698 : : }
1699 : :
1700 : 48 : spdk_jsonrpc_send_bool_response(request, true);
1701 : : }
1702 : 588 : SPDK_RPC_REGISTER("iscsi_set_options", rpc_iscsi_set_options, SPDK_RPC_STARTUP)
|