]> git.proxmox.com Git - ceph.git/blob - ceph/src/spdk/lib/bdev/lvol/vbdev_lvol_rpc.c
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / spdk / lib / bdev / lvol / vbdev_lvol_rpc.c
1 /*-
2 * BSD LICENSE
3 *
4 * Copyright (c) Intel Corporation.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
16 * distribution.
17 * * Neither the name of Intel Corporation nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34 #include "spdk/rpc.h"
35 #include "spdk/bdev.h"
36 #include "spdk/util.h"
37 #include "vbdev_lvol.h"
38 #include "spdk/string.h"
39 #include "spdk_internal/log.h"
40
41 SPDK_LOG_REGISTER_COMPONENT("lvolrpc", SPDK_LOG_LVOL_RPC)
42
43 struct rpc_construct_lvol_store {
44 char *lvs_name;
45 char *bdev_name;
46 uint32_t cluster_sz;
47 };
48
49 static int
50 vbdev_get_lvol_store_by_uuid_xor_name(const char *uuid, const char *lvs_name,
51 struct spdk_lvol_store **lvs)
52 {
53 if ((uuid == NULL && lvs_name == NULL)) {
54 SPDK_INFOLOG(SPDK_LOG_LVOL_RPC, "lvs UUID nor lvs name specified\n");
55 return -EINVAL;
56 } else if ((uuid && lvs_name)) {
57 SPDK_INFOLOG(SPDK_LOG_LVOL_RPC, "both lvs UUID '%s' and lvs name '%s' specified\n", uuid,
58 lvs_name);
59 return -EINVAL;
60 } else if (uuid) {
61 *lvs = vbdev_get_lvol_store_by_uuid(uuid);
62
63 if (*lvs == NULL) {
64 SPDK_INFOLOG(SPDK_LOG_LVOL_RPC, "blobstore with UUID '%s' not found\n", uuid);
65 return -ENODEV;
66 }
67 } else if (lvs_name) {
68
69 *lvs = vbdev_get_lvol_store_by_name(lvs_name);
70
71 if (*lvs == NULL) {
72 SPDK_INFOLOG(SPDK_LOG_LVOL_RPC, "blobstore with name '%s' not found\n", lvs_name);
73 return -ENODEV;
74 }
75 }
76 return 0;
77 }
78
79 static void
80 free_rpc_construct_lvol_store(struct rpc_construct_lvol_store *req)
81 {
82 free(req->bdev_name);
83 free(req->lvs_name);
84 }
85
86 static const struct spdk_json_object_decoder rpc_construct_lvol_store_decoders[] = {
87 {"bdev_name", offsetof(struct rpc_construct_lvol_store, bdev_name), spdk_json_decode_string},
88 {"cluster_sz", offsetof(struct rpc_construct_lvol_store, cluster_sz), spdk_json_decode_uint32, true},
89 {"lvs_name", offsetof(struct rpc_construct_lvol_store, lvs_name), spdk_json_decode_string},
90 };
91
92 static void
93 _spdk_rpc_lvol_store_construct_cb(void *cb_arg, struct spdk_lvol_store *lvol_store, int lvserrno)
94 {
95 struct spdk_json_write_ctx *w;
96 char lvol_store_uuid[SPDK_UUID_STRING_LEN];
97 struct spdk_jsonrpc_request *request = cb_arg;
98
99 if (lvserrno != 0) {
100 goto invalid;
101 }
102
103 spdk_uuid_fmt_lower(lvol_store_uuid, sizeof(lvol_store_uuid), &lvol_store->uuid);
104
105 w = spdk_jsonrpc_begin_result(request);
106 if (w == NULL) {
107 return;
108 }
109
110 spdk_json_write_string(w, lvol_store_uuid);
111 spdk_jsonrpc_end_result(request, w);
112 return;
113
114 invalid:
115 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
116 spdk_strerror(-lvserrno));
117 }
118
119 static void
120 spdk_rpc_construct_lvol_store(struct spdk_jsonrpc_request *request,
121 const struct spdk_json_val *params)
122 {
123 struct rpc_construct_lvol_store req = {};
124 struct spdk_bdev *bdev;
125 int rc;
126
127 if (spdk_json_decode_object(params, rpc_construct_lvol_store_decoders,
128 SPDK_COUNTOF(rpc_construct_lvol_store_decoders),
129 &req)) {
130 SPDK_INFOLOG(SPDK_LOG_LVOL_RPC, "spdk_json_decode_object failed\n");
131 rc = -EINVAL;
132 goto invalid;
133 }
134
135 if (req.bdev_name == NULL) {
136 SPDK_ERRLOG("missing bdev_name param\n");
137 rc = -EINVAL;
138 goto invalid;
139 }
140
141 if (req.lvs_name == NULL) {
142 SPDK_ERRLOG("missing lvs_name param\n");
143 rc = -EINVAL;
144 goto invalid;
145 }
146 bdev = spdk_bdev_get_by_name(req.bdev_name);
147 if (bdev == NULL) {
148 SPDK_ERRLOG("bdev '%s' does not exist\n", req.bdev_name);
149 rc = -ENODEV;
150 goto invalid;
151 }
152
153 rc = vbdev_lvs_create(bdev, req.lvs_name, req.cluster_sz, _spdk_rpc_lvol_store_construct_cb,
154 request);
155 if (rc < 0) {
156 goto invalid;
157 }
158 free_rpc_construct_lvol_store(&req);
159
160 return;
161
162 invalid:
163 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
164 spdk_strerror(-rc));
165 free_rpc_construct_lvol_store(&req);
166 }
167 SPDK_RPC_REGISTER("construct_lvol_store", spdk_rpc_construct_lvol_store, SPDK_RPC_RUNTIME)
168
169 struct rpc_rename_lvol_store {
170 char *old_name;
171 char *new_name;
172 };
173
174 static void
175 free_rpc_rename_lvol_store(struct rpc_rename_lvol_store *req)
176 {
177 free(req->old_name);
178 free(req->new_name);
179 }
180
181 static const struct spdk_json_object_decoder rpc_rename_lvol_store_decoders[] = {
182 {"old_name", offsetof(struct rpc_rename_lvol_store, old_name), spdk_json_decode_string},
183 {"new_name", offsetof(struct rpc_rename_lvol_store, new_name), spdk_json_decode_string},
184 };
185
186 static void
187 _spdk_rpc_rename_lvol_store_cb(void *cb_arg, int lvserrno)
188 {
189 struct spdk_json_write_ctx *w;
190 struct spdk_jsonrpc_request *request = cb_arg;
191
192 if (lvserrno != 0) {
193 goto invalid;
194 }
195
196 w = spdk_jsonrpc_begin_result(request);
197 if (w == NULL) {
198 return;
199 }
200
201 spdk_json_write_bool(w, true);
202 spdk_jsonrpc_end_result(request, w);
203 return;
204
205 invalid:
206 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
207 spdk_strerror(-lvserrno));
208 }
209
210 static void
211 spdk_rpc_rename_lvol_store(struct spdk_jsonrpc_request *request,
212 const struct spdk_json_val *params)
213 {
214 struct rpc_rename_lvol_store req = {};
215 struct spdk_lvol_store *lvs;
216 int rc;
217
218 if (spdk_json_decode_object(params, rpc_rename_lvol_store_decoders,
219 SPDK_COUNTOF(rpc_rename_lvol_store_decoders),
220 &req)) {
221 SPDK_INFOLOG(SPDK_LOG_LVOL_RPC, "spdk_json_decode_object failed\n");
222 rc = -EINVAL;
223 goto invalid;
224 }
225
226 lvs = vbdev_get_lvol_store_by_name(req.old_name);
227 if (lvs == NULL) {
228 SPDK_INFOLOG(SPDK_LOG_LVOL_RPC, "no lvs existing for given name\n");
229 rc = -ENOENT;
230 goto invalid;
231 }
232
233 vbdev_lvs_rename(lvs, req.new_name, _spdk_rpc_rename_lvol_store_cb, request);
234
235 free_rpc_rename_lvol_store(&req);
236
237 return;
238
239 invalid:
240 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, spdk_strerror(-rc));
241 free_rpc_rename_lvol_store(&req);
242 }
243 SPDK_RPC_REGISTER("rename_lvol_store", spdk_rpc_rename_lvol_store, SPDK_RPC_RUNTIME)
244
245 struct rpc_destroy_lvol_store {
246 char *uuid;
247 char *lvs_name;
248 };
249
250 static void
251 free_rpc_destroy_lvol_store(struct rpc_destroy_lvol_store *req)
252 {
253 free(req->uuid);
254 free(req->lvs_name);
255 }
256
257 static const struct spdk_json_object_decoder rpc_destroy_lvol_store_decoders[] = {
258 {"uuid", offsetof(struct rpc_destroy_lvol_store, uuid), spdk_json_decode_string, true},
259 {"lvs_name", offsetof(struct rpc_destroy_lvol_store, lvs_name), spdk_json_decode_string, true},
260 };
261
262 static void
263 _spdk_rpc_lvol_store_destroy_cb(void *cb_arg, int lvserrno)
264 {
265 struct spdk_json_write_ctx *w;
266 struct spdk_jsonrpc_request *request = cb_arg;
267
268 if (lvserrno != 0) {
269 goto invalid;
270 }
271
272 w = spdk_jsonrpc_begin_result(request);
273 if (w == NULL) {
274 return;
275 }
276
277 spdk_json_write_bool(w, true);
278 spdk_jsonrpc_end_result(request, w);
279 return;
280
281 invalid:
282 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
283 spdk_strerror(-lvserrno));
284 }
285
286 static void
287 spdk_rpc_destroy_lvol_store(struct spdk_jsonrpc_request *request,
288 const struct spdk_json_val *params)
289 {
290 struct rpc_destroy_lvol_store req = {};
291 struct spdk_lvol_store *lvs = NULL;
292 int rc;
293
294 if (spdk_json_decode_object(params, rpc_destroy_lvol_store_decoders,
295 SPDK_COUNTOF(rpc_destroy_lvol_store_decoders),
296 &req)) {
297 SPDK_INFOLOG(SPDK_LOG_LVOL_RPC, "spdk_json_decode_object failed\n");
298 rc = -EINVAL;
299 goto invalid;
300 }
301
302 rc = vbdev_get_lvol_store_by_uuid_xor_name(req.uuid, req.lvs_name, &lvs);
303 if (rc != 0) {
304 goto invalid;
305 }
306
307 vbdev_lvs_destruct(lvs, _spdk_rpc_lvol_store_destroy_cb, request);
308
309 free_rpc_destroy_lvol_store(&req);
310
311 return;
312
313 invalid:
314 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
315 spdk_strerror(-rc));
316 free_rpc_destroy_lvol_store(&req);
317 }
318 SPDK_RPC_REGISTER("destroy_lvol_store", spdk_rpc_destroy_lvol_store, SPDK_RPC_RUNTIME)
319
320 struct rpc_construct_lvol_bdev {
321 char *uuid;
322 char *lvs_name;
323 char *lvol_name;
324 uint64_t size;
325 bool thin_provision;
326 };
327
328 static void
329 free_rpc_construct_lvol_bdev(struct rpc_construct_lvol_bdev *req)
330 {
331 free(req->uuid);
332 free(req->lvs_name);
333 free(req->lvol_name);
334 }
335
336 static const struct spdk_json_object_decoder rpc_construct_lvol_bdev_decoders[] = {
337 {"uuid", offsetof(struct rpc_construct_lvol_bdev, uuid), spdk_json_decode_string, true},
338 {"lvs_name", offsetof(struct rpc_construct_lvol_bdev, lvs_name), spdk_json_decode_string, true},
339 {"lvol_name", offsetof(struct rpc_construct_lvol_bdev, lvol_name), spdk_json_decode_string, true},
340 {"size", offsetof(struct rpc_construct_lvol_bdev, size), spdk_json_decode_uint64},
341 {"thin_provision", offsetof(struct rpc_construct_lvol_bdev, thin_provision), spdk_json_decode_bool, true},
342 };
343
344 static void
345 _spdk_rpc_construct_lvol_bdev_cb(void *cb_arg, struct spdk_lvol *lvol, int lvolerrno)
346 {
347 struct spdk_json_write_ctx *w;
348 struct spdk_jsonrpc_request *request = cb_arg;
349
350 if (lvolerrno != 0) {
351 goto invalid;
352 }
353
354 w = spdk_jsonrpc_begin_result(request);
355 if (w == NULL) {
356 return;
357 }
358
359 spdk_json_write_string(w, lvol->unique_id);
360 spdk_jsonrpc_end_result(request, w);
361 return;
362
363 invalid:
364 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
365 spdk_strerror(-lvolerrno));
366 }
367
368 static void
369 spdk_rpc_construct_lvol_bdev(struct spdk_jsonrpc_request *request,
370 const struct spdk_json_val *params)
371 {
372 struct rpc_construct_lvol_bdev req = {};
373 int rc;
374 struct spdk_lvol_store *lvs = NULL;
375
376 SPDK_INFOLOG(SPDK_LOG_LVOL_RPC, "Creating blob\n");
377
378 if (spdk_json_decode_object(params, rpc_construct_lvol_bdev_decoders,
379 SPDK_COUNTOF(rpc_construct_lvol_bdev_decoders),
380 &req)) {
381 SPDK_INFOLOG(SPDK_LOG_LVOL_RPC, "spdk_json_decode_object failed\n");
382 rc = -EINVAL;
383 goto invalid;
384 }
385
386 rc = vbdev_get_lvol_store_by_uuid_xor_name(req.uuid, req.lvs_name, &lvs);
387 if (rc != 0) {
388 goto invalid;
389 }
390
391 if (req.lvol_name == NULL) {
392 SPDK_INFOLOG(SPDK_LOG_LVOL_RPC, "no bdev name\n");
393 rc = -EINVAL;
394 goto invalid;
395 }
396
397 rc = vbdev_lvol_create(lvs, req.lvol_name, req.size, req.thin_provision,
398 _spdk_rpc_construct_lvol_bdev_cb, request);
399 if (rc < 0) {
400 goto invalid;
401 }
402
403 free_rpc_construct_lvol_bdev(&req);
404 return;
405
406 invalid:
407 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
408 spdk_strerror(-rc));
409 free_rpc_construct_lvol_bdev(&req);
410 }
411
412 SPDK_RPC_REGISTER("construct_lvol_bdev", spdk_rpc_construct_lvol_bdev, SPDK_RPC_RUNTIME)
413
414 struct rpc_snapshot_lvol_bdev {
415 char *lvol_name;
416 char *snapshot_name;
417 };
418
419 static void
420 free_rpc_snapshot_lvol_bdev(struct rpc_snapshot_lvol_bdev *req)
421 {
422 free(req->lvol_name);
423 free(req->snapshot_name);
424 }
425
426 static const struct spdk_json_object_decoder rpc_snapshot_lvol_bdev_decoders[] = {
427 {"lvol_name", offsetof(struct rpc_snapshot_lvol_bdev, lvol_name), spdk_json_decode_string},
428 {"snapshot_name", offsetof(struct rpc_snapshot_lvol_bdev, snapshot_name), spdk_json_decode_string},
429 };
430
431 static void
432 _spdk_rpc_snapshot_lvol_bdev_cb(void *cb_arg, struct spdk_lvol *lvol, int lvolerrno)
433 {
434 struct spdk_json_write_ctx *w;
435 struct spdk_jsonrpc_request *request = cb_arg;
436
437 if (lvolerrno != 0) {
438 goto invalid;
439 }
440
441 w = spdk_jsonrpc_begin_result(request);
442 if (w == NULL) {
443 return;
444 }
445
446 spdk_json_write_string(w, lvol->unique_id);
447 spdk_jsonrpc_end_result(request, w);
448 return;
449
450 invalid:
451 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
452 spdk_strerror(-lvolerrno));
453 }
454
455 static void
456 spdk_rpc_snapshot_lvol_bdev(struct spdk_jsonrpc_request *request,
457 const struct spdk_json_val *params)
458 {
459 struct rpc_snapshot_lvol_bdev req = {};
460 struct spdk_bdev *bdev;
461 struct spdk_lvol *lvol;
462 int rc;
463
464 SPDK_INFOLOG(SPDK_LOG_LVOL_RPC, "Snapshotting blob\n");
465
466 if (spdk_json_decode_object(params, rpc_snapshot_lvol_bdev_decoders,
467 SPDK_COUNTOF(rpc_snapshot_lvol_bdev_decoders),
468 &req)) {
469 SPDK_INFOLOG(SPDK_LOG_LVOL_RPC, "spdk_json_decode_object failed\n");
470 rc = -EINVAL;
471 goto invalid;
472 }
473
474 bdev = spdk_bdev_get_by_name(req.lvol_name);
475 if (bdev == NULL) {
476 SPDK_INFOLOG(SPDK_LOG_LVOL_RPC, "bdev '%s' does not exist\n", req.lvol_name);
477 rc = -ENODEV;
478 goto invalid;
479 }
480
481 lvol = vbdev_lvol_get_from_bdev(bdev);
482 if (lvol == NULL) {
483 SPDK_ERRLOG("lvol does not exist\n");
484 rc = -ENODEV;
485 goto invalid;
486 }
487
488 vbdev_lvol_create_snapshot(lvol, req.snapshot_name, _spdk_rpc_snapshot_lvol_bdev_cb, request);
489
490 free_rpc_snapshot_lvol_bdev(&req);
491 return;
492
493 invalid:
494 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, spdk_strerror(-rc));
495 free_rpc_snapshot_lvol_bdev(&req);
496 }
497
498 SPDK_RPC_REGISTER("snapshot_lvol_bdev", spdk_rpc_snapshot_lvol_bdev, SPDK_RPC_RUNTIME)
499
500 struct rpc_clone_lvol_bdev {
501 char *snapshot_name;
502 char *clone_name;
503 };
504
505 static void
506 free_rpc_clone_lvol_bdev(struct rpc_clone_lvol_bdev *req)
507 {
508 free(req->snapshot_name);
509 free(req->clone_name);
510 }
511
512 static const struct spdk_json_object_decoder rpc_clone_lvol_bdev_decoders[] = {
513 {"snapshot_name", offsetof(struct rpc_clone_lvol_bdev, snapshot_name), spdk_json_decode_string},
514 {"clone_name", offsetof(struct rpc_clone_lvol_bdev, clone_name), spdk_json_decode_string, true},
515 };
516
517 static void
518 _spdk_rpc_clone_lvol_bdev_cb(void *cb_arg, struct spdk_lvol *lvol, int lvolerrno)
519 {
520 struct spdk_json_write_ctx *w;
521 struct spdk_jsonrpc_request *request = cb_arg;
522
523 if (lvolerrno != 0) {
524 goto invalid;
525 }
526
527 w = spdk_jsonrpc_begin_result(request);
528 if (w == NULL) {
529 return;
530 }
531
532 spdk_json_write_string(w, lvol->unique_id);
533 spdk_jsonrpc_end_result(request, w);
534 return;
535
536 invalid:
537 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
538 spdk_strerror(-lvolerrno));
539 }
540
541 static void
542 spdk_rpc_clone_lvol_bdev(struct spdk_jsonrpc_request *request,
543 const struct spdk_json_val *params)
544 {
545 struct rpc_clone_lvol_bdev req = {};
546 struct spdk_bdev *bdev;
547 struct spdk_lvol *lvol;
548 int rc;
549
550 SPDK_INFOLOG(SPDK_LOG_LVOL_RPC, "Cloning blob\n");
551
552 if (spdk_json_decode_object(params, rpc_clone_lvol_bdev_decoders,
553 SPDK_COUNTOF(rpc_clone_lvol_bdev_decoders),
554 &req)) {
555 SPDK_INFOLOG(SPDK_LOG_LVOL_RPC, "spdk_json_decode_object failed\n");
556 rc = -EINVAL;
557 goto invalid;
558 }
559
560 bdev = spdk_bdev_get_by_name(req.snapshot_name);
561 if (bdev == NULL) {
562 SPDK_INFOLOG(SPDK_LOG_LVOL_RPC, "bdev '%s' does not exist\n", req.snapshot_name);
563 rc = -ENODEV;
564 goto invalid;
565 }
566
567 lvol = vbdev_lvol_get_from_bdev(bdev);
568 if (lvol == NULL) {
569 SPDK_ERRLOG("lvol does not exist\n");
570 rc = -ENODEV;
571 goto invalid;
572 }
573
574 vbdev_lvol_create_clone(lvol, req.clone_name, _spdk_rpc_clone_lvol_bdev_cb, request);
575
576 free_rpc_clone_lvol_bdev(&req);
577 return;
578
579 invalid:
580 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, spdk_strerror(-rc));
581 free_rpc_clone_lvol_bdev(&req);
582 }
583
584 SPDK_RPC_REGISTER("clone_lvol_bdev", spdk_rpc_clone_lvol_bdev, SPDK_RPC_RUNTIME)
585
586 struct rpc_rename_lvol_bdev {
587 char *old_name;
588 char *new_name;
589 };
590
591 static void
592 free_rpc_rename_lvol_bdev(struct rpc_rename_lvol_bdev *req)
593 {
594 free(req->old_name);
595 free(req->new_name);
596 }
597
598 static const struct spdk_json_object_decoder rpc_rename_lvol_bdev_decoders[] = {
599 {"old_name", offsetof(struct rpc_rename_lvol_bdev, old_name), spdk_json_decode_string},
600 {"new_name", offsetof(struct rpc_rename_lvol_bdev, new_name), spdk_json_decode_string},
601 };
602
603 static void
604 _spdk_rpc_rename_lvol_bdev_cb(void *cb_arg, int lvolerrno)
605 {
606 struct spdk_json_write_ctx *w;
607 struct spdk_jsonrpc_request *request = cb_arg;
608
609 if (lvolerrno != 0) {
610 goto invalid;
611 }
612
613 w = spdk_jsonrpc_begin_result(request);
614 if (w == NULL) {
615 return;
616 }
617
618 spdk_json_write_bool(w, true);
619 spdk_jsonrpc_end_result(request, w);
620 return;
621
622 invalid:
623 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
624 spdk_strerror(-lvolerrno));
625 }
626
627 static void
628 spdk_rpc_rename_lvol_bdev(struct spdk_jsonrpc_request *request,
629 const struct spdk_json_val *params)
630 {
631 struct rpc_rename_lvol_bdev req = {};
632 struct spdk_bdev *bdev;
633 struct spdk_lvol *lvol;
634 int rc = 0;
635
636 SPDK_INFOLOG(SPDK_LOG_LVOL_RPC, "Renaming lvol\n");
637
638 if (spdk_json_decode_object(params, rpc_rename_lvol_bdev_decoders,
639 SPDK_COUNTOF(rpc_rename_lvol_bdev_decoders),
640 &req)) {
641 SPDK_INFOLOG(SPDK_LOG_LVOL_RPC, "spdk_json_decode_object failed\n");
642 rc = -EINVAL;
643 goto invalid;
644 }
645
646 bdev = spdk_bdev_get_by_name(req.old_name);
647 if (bdev == NULL) {
648 SPDK_ERRLOG("bdev '%s' does not exist\n", req.old_name);
649 rc = -ENODEV;
650 goto invalid;
651 }
652
653 lvol = vbdev_lvol_get_from_bdev(bdev);
654 if (lvol == NULL) {
655 SPDK_ERRLOG("lvol does not exist\n");
656 rc = -ENODEV;
657 goto invalid;
658 }
659
660 vbdev_lvol_rename(lvol, req.new_name, _spdk_rpc_rename_lvol_bdev_cb, request);
661
662 free_rpc_rename_lvol_bdev(&req);
663 return;
664
665 invalid:
666 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, spdk_strerror(-rc));
667 free_rpc_rename_lvol_bdev(&req);
668 }
669
670 SPDK_RPC_REGISTER("rename_lvol_bdev", spdk_rpc_rename_lvol_bdev, SPDK_RPC_RUNTIME)
671
672 struct rpc_inflate_lvol_bdev {
673 char *name;
674 };
675
676 static void
677 free_rpc_inflate_lvol_bdev(struct rpc_inflate_lvol_bdev *req)
678 {
679 free(req->name);
680 }
681
682 static const struct spdk_json_object_decoder rpc_inflate_lvol_bdev_decoders[] = {
683 {"name", offsetof(struct rpc_inflate_lvol_bdev, name), spdk_json_decode_string},
684 };
685
686 static void
687 _spdk_rpc_inflate_lvol_bdev_cb(void *cb_arg, int lvolerrno)
688 {
689 struct spdk_json_write_ctx *w;
690 struct spdk_jsonrpc_request *request = cb_arg;
691
692 if (lvolerrno != 0) {
693 goto invalid;
694 }
695
696 w = spdk_jsonrpc_begin_result(request);
697 if (w == NULL) {
698 return;
699 }
700
701 spdk_json_write_bool(w, true);
702 spdk_jsonrpc_end_result(request, w);
703 return;
704
705 invalid:
706 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
707 spdk_strerror(-lvolerrno));
708 }
709
710 static void
711 spdk_rpc_inflate_lvol_bdev(struct spdk_jsonrpc_request *request,
712 const struct spdk_json_val *params)
713 {
714 struct rpc_inflate_lvol_bdev req = {};
715 struct spdk_bdev *bdev;
716 struct spdk_lvol *lvol;
717 int rc = 0;
718
719 SPDK_INFOLOG(SPDK_LOG_LVOL_RPC, "Inflating lvol\n");
720
721 if (spdk_json_decode_object(params, rpc_inflate_lvol_bdev_decoders,
722 SPDK_COUNTOF(rpc_inflate_lvol_bdev_decoders),
723 &req)) {
724 SPDK_INFOLOG(SPDK_LOG_LVOL_RPC, "spdk_json_decode_object failed\n");
725 rc = -EINVAL;
726 goto invalid;
727 }
728
729 bdev = spdk_bdev_get_by_name(req.name);
730 if (bdev == NULL) {
731 SPDK_ERRLOG("bdev '%s' does not exist\n", req.name);
732 rc = -ENODEV;
733 goto invalid;
734 }
735
736 lvol = vbdev_lvol_get_from_bdev(bdev);
737 if (lvol == NULL) {
738 SPDK_ERRLOG("lvol does not exist\n");
739 rc = -ENODEV;
740 goto invalid;
741 }
742
743 spdk_lvol_inflate(lvol, _spdk_rpc_inflate_lvol_bdev_cb, request);
744
745 free_rpc_inflate_lvol_bdev(&req);
746 return;
747
748 invalid:
749 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, spdk_strerror(-rc));
750 free_rpc_inflate_lvol_bdev(&req);
751 }
752
753 SPDK_RPC_REGISTER("inflate_lvol_bdev", spdk_rpc_inflate_lvol_bdev, SPDK_RPC_RUNTIME)
754
755 static void
756 spdk_rpc_decouple_parent_lvol_bdev(struct spdk_jsonrpc_request *request,
757 const struct spdk_json_val *params)
758 {
759 struct rpc_inflate_lvol_bdev req = {};
760 struct spdk_bdev *bdev;
761 struct spdk_lvol *lvol;
762 int rc = 0;
763
764 SPDK_INFOLOG(SPDK_LOG_LVOL_RPC, "Decoupling parent of lvol\n");
765
766 if (spdk_json_decode_object(params, rpc_inflate_lvol_bdev_decoders,
767 SPDK_COUNTOF(rpc_inflate_lvol_bdev_decoders),
768 &req)) {
769 SPDK_INFOLOG(SPDK_LOG_LVOL_RPC, "spdk_json_decode_object failed\n");
770 rc = -EINVAL;
771 goto invalid;
772 }
773
774 bdev = spdk_bdev_get_by_name(req.name);
775 if (bdev == NULL) {
776 SPDK_ERRLOG("bdev '%s' does not exist\n", req.name);
777 rc = -ENODEV;
778 goto invalid;
779 }
780
781 lvol = vbdev_lvol_get_from_bdev(bdev);
782 if (lvol == NULL) {
783 SPDK_ERRLOG("lvol does not exist\n");
784 rc = -ENODEV;
785 goto invalid;
786 }
787
788 spdk_lvol_decouple_parent(lvol, _spdk_rpc_inflate_lvol_bdev_cb, request);
789
790 free_rpc_inflate_lvol_bdev(&req);
791 return;
792
793 invalid:
794 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, spdk_strerror(-rc));
795 free_rpc_inflate_lvol_bdev(&req);
796 }
797
798 SPDK_RPC_REGISTER("decouple_parent_lvol_bdev", spdk_rpc_decouple_parent_lvol_bdev, SPDK_RPC_RUNTIME)
799
800 struct rpc_resize_lvol_bdev {
801 char *name;
802 uint64_t size;
803 };
804
805 static void
806 free_rpc_resize_lvol_bdev(struct rpc_resize_lvol_bdev *req)
807 {
808 free(req->name);
809 }
810
811 static const struct spdk_json_object_decoder rpc_resize_lvol_bdev_decoders[] = {
812 {"name", offsetof(struct rpc_resize_lvol_bdev, name), spdk_json_decode_string},
813 {"size", offsetof(struct rpc_resize_lvol_bdev, size), spdk_json_decode_uint64},
814 };
815
816 static void
817 _spdk_rpc_resize_lvol_bdev_cb(void *cb_arg, int lvolerrno)
818 {
819 struct spdk_json_write_ctx *w;
820 struct spdk_jsonrpc_request *request = cb_arg;
821
822 if (lvolerrno != 0) {
823 goto invalid;
824 }
825
826 w = spdk_jsonrpc_begin_result(request);
827 if (w == NULL) {
828 return;
829 }
830
831 spdk_json_write_bool(w, true);
832 spdk_jsonrpc_end_result(request, w);
833 return;
834
835 invalid:
836 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
837 spdk_strerror(-lvolerrno));
838 }
839
840 static void
841 spdk_rpc_resize_lvol_bdev(struct spdk_jsonrpc_request *request,
842 const struct spdk_json_val *params)
843 {
844 struct rpc_resize_lvol_bdev req = {};
845 struct spdk_bdev *bdev;
846 struct spdk_lvol *lvol;
847 int rc = 0;
848
849 SPDK_INFOLOG(SPDK_LOG_LVOL_RPC, "Resizing lvol\n");
850
851 if (spdk_json_decode_object(params, rpc_resize_lvol_bdev_decoders,
852 SPDK_COUNTOF(rpc_resize_lvol_bdev_decoders),
853 &req)) {
854 SPDK_INFOLOG(SPDK_LOG_LVOL_RPC, "spdk_json_decode_object failed\n");
855 rc = -EINVAL;
856 goto invalid;
857 }
858
859 if (req.name == NULL) {
860 SPDK_ERRLOG("missing name param\n");
861 rc = -EINVAL;
862 goto invalid;
863 }
864
865 bdev = spdk_bdev_get_by_name(req.name);
866 if (bdev == NULL) {
867 SPDK_ERRLOG("no bdev for provided name %s\n", req.name);
868 rc = -ENODEV;
869 goto invalid;
870 }
871
872 lvol = vbdev_lvol_get_from_bdev(bdev);
873 if (lvol == NULL) {
874 rc = -ENODEV;
875 goto invalid;
876 }
877
878 vbdev_lvol_resize(lvol, req.size, _spdk_rpc_resize_lvol_bdev_cb, request);
879
880 free_rpc_resize_lvol_bdev(&req);
881 return;
882
883 invalid:
884 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
885 spdk_strerror(-rc));
886 free_rpc_resize_lvol_bdev(&req);
887 }
888
889 SPDK_RPC_REGISTER("resize_lvol_bdev", spdk_rpc_resize_lvol_bdev, SPDK_RPC_RUNTIME)
890
891 struct rpc_destroy_lvol_bdev {
892 char *name;
893 };
894
895 static void
896 free_rpc_destroy_lvol_bdev(struct rpc_destroy_lvol_bdev *req)
897 {
898 free(req->name);
899 }
900
901 static const struct spdk_json_object_decoder rpc_destroy_lvol_bdev_decoders[] = {
902 {"name", offsetof(struct rpc_destroy_lvol_bdev, name), spdk_json_decode_string},
903 };
904
905 static void
906 _spdk_rpc_destroy_lvol_bdev_cb(void *cb_arg, int lvolerrno)
907 {
908 struct spdk_json_write_ctx *w;
909 struct spdk_jsonrpc_request *request = cb_arg;
910
911 if (lvolerrno != 0) {
912 goto invalid;
913 }
914
915 w = spdk_jsonrpc_begin_result(request);
916 if (w == NULL) {
917 return;
918 }
919
920 spdk_json_write_bool(w, true);
921 spdk_jsonrpc_end_result(request, w);
922 return;
923
924 invalid:
925 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
926 spdk_strerror(-lvolerrno));
927 }
928
929 static void
930 spdk_rpc_destroy_lvol_bdev(struct spdk_jsonrpc_request *request,
931 const struct spdk_json_val *params)
932 {
933 struct rpc_destroy_lvol_bdev req = {};
934 struct spdk_bdev *bdev;
935 struct spdk_lvol *lvol;
936 int rc;
937
938 if (spdk_json_decode_object(params, rpc_destroy_lvol_bdev_decoders,
939 SPDK_COUNTOF(rpc_destroy_lvol_bdev_decoders),
940 &req)) {
941 SPDK_INFOLOG(SPDK_LOG_LVOL_RPC, "spdk_json_decode_object failed\n");
942 rc = -EINVAL;
943 goto invalid;
944 }
945
946 bdev = spdk_bdev_get_by_name(req.name);
947 if (bdev == NULL) {
948 SPDK_ERRLOG("no bdev for provided name %s\n", req.name);
949 rc = -ENODEV;
950 goto invalid;
951 }
952
953 lvol = vbdev_lvol_get_from_bdev(bdev);
954 if (lvol == NULL) {
955 rc = -ENODEV;
956 goto invalid;
957 }
958
959 vbdev_lvol_destroy(lvol, _spdk_rpc_destroy_lvol_bdev_cb, request);
960
961 free_rpc_destroy_lvol_bdev(&req);
962 return;
963
964 invalid:
965 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
966 spdk_strerror(-rc));
967 free_rpc_destroy_lvol_bdev(&req);
968 }
969
970 SPDK_RPC_REGISTER("destroy_lvol_bdev", spdk_rpc_destroy_lvol_bdev, SPDK_RPC_RUNTIME)
971
972 struct rpc_get_lvol_stores {
973 char *uuid;
974 char *lvs_name;
975 };
976
977 static void
978 free_rpc_get_lvol_stores(struct rpc_get_lvol_stores *req)
979 {
980 free(req->uuid);
981 free(req->lvs_name);
982 }
983
984 static const struct spdk_json_object_decoder rpc_get_lvol_stores_decoders[] = {
985 {"uuid", offsetof(struct rpc_get_lvol_stores, uuid), spdk_json_decode_string, true},
986 {"lvs_name", offsetof(struct rpc_get_lvol_stores, lvs_name), spdk_json_decode_string, true},
987 };
988
989 static void
990 spdk_rpc_dump_lvol_store_info(struct spdk_json_write_ctx *w, struct lvol_store_bdev *lvs_bdev)
991 {
992 struct spdk_blob_store *bs;
993 uint64_t cluster_size, block_size;
994 char uuid[SPDK_UUID_STRING_LEN];
995
996 bs = lvs_bdev->lvs->blobstore;
997 cluster_size = spdk_bs_get_cluster_size(bs);
998 /* Block size of lvols is always size of blob store page */
999 block_size = spdk_bs_get_page_size(bs);
1000
1001 spdk_json_write_object_begin(w);
1002
1003 spdk_uuid_fmt_lower(uuid, sizeof(uuid), &lvs_bdev->lvs->uuid);
1004 spdk_json_write_name(w, "uuid");
1005 spdk_json_write_string(w, uuid);
1006
1007 spdk_json_write_name(w, "name");
1008 spdk_json_write_string(w, lvs_bdev->lvs->name);
1009
1010 spdk_json_write_name(w, "base_bdev");
1011 spdk_json_write_string(w, spdk_bdev_get_name(lvs_bdev->bdev));
1012
1013 spdk_json_write_name(w, "total_data_clusters");
1014 spdk_json_write_uint64(w, spdk_bs_total_data_cluster_count(bs));
1015
1016 spdk_json_write_name(w, "free_clusters");
1017 spdk_json_write_uint64(w, spdk_bs_free_cluster_count(bs));
1018
1019 spdk_json_write_name(w, "block_size");
1020 spdk_json_write_uint64(w, block_size);
1021
1022 spdk_json_write_name(w, "cluster_size");
1023 spdk_json_write_uint64(w, cluster_size);
1024
1025 spdk_json_write_object_end(w);
1026 }
1027
1028 static void
1029 spdk_rpc_get_lvol_stores(struct spdk_jsonrpc_request *request,
1030 const struct spdk_json_val *params)
1031 {
1032 struct rpc_get_lvol_stores req = {};
1033 struct spdk_json_write_ctx *w;
1034 struct lvol_store_bdev *lvs_bdev = NULL;
1035 struct spdk_lvol_store *lvs = NULL;
1036 int rc;
1037
1038 if (params != NULL) {
1039 if (spdk_json_decode_object(params, rpc_get_lvol_stores_decoders,
1040 SPDK_COUNTOF(rpc_get_lvol_stores_decoders),
1041 &req)) {
1042 SPDK_INFOLOG(SPDK_LOG_LVOL_RPC, "spdk_json_decode_object failed\n");
1043 rc = -EINVAL;
1044 goto invalid;
1045 }
1046
1047 rc = vbdev_get_lvol_store_by_uuid_xor_name(req.uuid, req.lvs_name, &lvs);
1048 if (rc != 0) {
1049 goto invalid;
1050 }
1051
1052 lvs_bdev = vbdev_get_lvs_bdev_by_lvs(lvs);
1053 if (lvs_bdev == NULL) {
1054 rc = -ENODEV;
1055 goto invalid;
1056 }
1057 }
1058
1059 w = spdk_jsonrpc_begin_result(request);
1060 if (w == NULL) {
1061 free_rpc_get_lvol_stores(&req);
1062 return;
1063 }
1064
1065 spdk_json_write_array_begin(w);
1066
1067 if (lvs_bdev != NULL) {
1068 spdk_rpc_dump_lvol_store_info(w, lvs_bdev);
1069 } else {
1070 for (lvs_bdev = vbdev_lvol_store_first(); lvs_bdev != NULL;
1071 lvs_bdev = vbdev_lvol_store_next(lvs_bdev)) {
1072 spdk_rpc_dump_lvol_store_info(w, lvs_bdev);
1073 }
1074 }
1075 spdk_json_write_array_end(w);
1076
1077 spdk_jsonrpc_end_result(request, w);
1078
1079 free_rpc_get_lvol_stores(&req);
1080
1081 return;
1082
1083 invalid:
1084 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
1085 spdk_strerror(-rc));
1086 free_rpc_get_lvol_stores(&req);
1087 }
1088
1089 SPDK_RPC_REGISTER("get_lvol_stores", spdk_rpc_get_lvol_stores, SPDK_RPC_RUNTIME)