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 char *clear_method; 48 }; 49 50 static int 51 vbdev_get_lvol_store_by_uuid_xor_name(const char *uuid, const char *lvs_name, 52 struct spdk_lvol_store **lvs) 53 { 54 if ((uuid == NULL && lvs_name == NULL)) { 55 SPDK_INFOLOG(SPDK_LOG_LVOL_RPC, "lvs UUID nor lvs name specified\n"); 56 return -EINVAL; 57 } else if ((uuid && lvs_name)) { 58 SPDK_INFOLOG(SPDK_LOG_LVOL_RPC, "both lvs UUID '%s' and lvs name '%s' specified\n", uuid, 59 lvs_name); 60 return -EINVAL; 61 } else if (uuid) { 62 *lvs = vbdev_get_lvol_store_by_uuid(uuid); 63 64 if (*lvs == NULL) { 65 SPDK_INFOLOG(SPDK_LOG_LVOL_RPC, "blobstore with UUID '%s' not found\n", uuid); 66 return -ENODEV; 67 } 68 } else if (lvs_name) { 69 70 *lvs = vbdev_get_lvol_store_by_name(lvs_name); 71 72 if (*lvs == NULL) { 73 SPDK_INFOLOG(SPDK_LOG_LVOL_RPC, "blobstore with name '%s' not found\n", lvs_name); 74 return -ENODEV; 75 } 76 } 77 return 0; 78 } 79 80 static void 81 free_rpc_construct_lvol_store(struct rpc_construct_lvol_store *req) 82 { 83 free(req->bdev_name); 84 free(req->lvs_name); 85 free(req->clear_method); 86 } 87 88 static const struct spdk_json_object_decoder rpc_construct_lvol_store_decoders[] = { 89 {"bdev_name", offsetof(struct rpc_construct_lvol_store, bdev_name), spdk_json_decode_string}, 90 {"cluster_sz", offsetof(struct rpc_construct_lvol_store, cluster_sz), spdk_json_decode_uint32, true}, 91 {"lvs_name", offsetof(struct rpc_construct_lvol_store, lvs_name), spdk_json_decode_string}, 92 {"clear_method", offsetof(struct rpc_construct_lvol_store, clear_method), spdk_json_decode_string, true}, 93 }; 94 95 static void 96 _spdk_rpc_lvol_store_construct_cb(void *cb_arg, struct spdk_lvol_store *lvol_store, int lvserrno) 97 { 98 struct spdk_json_write_ctx *w; 99 char lvol_store_uuid[SPDK_UUID_STRING_LEN]; 100 struct spdk_jsonrpc_request *request = cb_arg; 101 102 if (lvserrno != 0) { 103 goto invalid; 104 } 105 106 spdk_uuid_fmt_lower(lvol_store_uuid, sizeof(lvol_store_uuid), &lvol_store->uuid); 107 108 w = spdk_jsonrpc_begin_result(request); 109 spdk_json_write_string(w, lvol_store_uuid); 110 spdk_jsonrpc_end_result(request, w); 111 return; 112 113 invalid: 114 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 115 spdk_strerror(-lvserrno)); 116 } 117 118 static void 119 spdk_rpc_construct_lvol_store(struct spdk_jsonrpc_request *request, 120 const struct spdk_json_val *params) 121 { 122 struct rpc_construct_lvol_store req = {}; 123 struct spdk_bdev *bdev; 124 int rc = 0; 125 enum lvs_clear_method clear_method; 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 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 132 "spdk_json_decode_object failed"); 133 goto cleanup; 134 } 135 136 bdev = spdk_bdev_get_by_name(req.bdev_name); 137 if (bdev == NULL) { 138 SPDK_ERRLOG("bdev '%s' does not exist\n", req.bdev_name); 139 spdk_jsonrpc_send_error_response_fmt(request, -ENODEV, "Bdev %s not found", req.bdev_name); 140 goto cleanup; 141 } 142 143 if (req.clear_method != NULL) { 144 if (!strcasecmp(req.clear_method, "none")) { 145 clear_method = LVS_CLEAR_WITH_NONE; 146 } else if (!strcasecmp(req.clear_method, "unmap")) { 147 clear_method = LVS_CLEAR_WITH_UNMAP; 148 } else if (!strcasecmp(req.clear_method, "write_zeroes")) { 149 clear_method = LVS_CLEAR_WITH_WRITE_ZEROES; 150 } else { 151 spdk_jsonrpc_send_error_response(request, -EINVAL, "Invalid clear_method parameter"); 152 goto cleanup; 153 } 154 } else { 155 clear_method = LVS_CLEAR_WITH_UNMAP; 156 } 157 158 rc = vbdev_lvs_create(bdev, req.lvs_name, req.cluster_sz, clear_method, 159 _spdk_rpc_lvol_store_construct_cb, request); 160 if (rc < 0) { 161 spdk_jsonrpc_send_error_response(request, -rc, spdk_strerror(rc)); 162 goto cleanup; 163 } 164 free_rpc_construct_lvol_store(&req); 165 166 return; 167 168 cleanup: 169 free_rpc_construct_lvol_store(&req); 170 } 171 SPDK_RPC_REGISTER("construct_lvol_store", spdk_rpc_construct_lvol_store, SPDK_RPC_RUNTIME) 172 173 struct rpc_rename_lvol_store { 174 char *old_name; 175 char *new_name; 176 }; 177 178 static void 179 free_rpc_rename_lvol_store(struct rpc_rename_lvol_store *req) 180 { 181 free(req->old_name); 182 free(req->new_name); 183 } 184 185 static const struct spdk_json_object_decoder rpc_rename_lvol_store_decoders[] = { 186 {"old_name", offsetof(struct rpc_rename_lvol_store, old_name), spdk_json_decode_string}, 187 {"new_name", offsetof(struct rpc_rename_lvol_store, new_name), spdk_json_decode_string}, 188 }; 189 190 static void 191 _spdk_rpc_rename_lvol_store_cb(void *cb_arg, int lvserrno) 192 { 193 struct spdk_json_write_ctx *w; 194 struct spdk_jsonrpc_request *request = cb_arg; 195 196 if (lvserrno != 0) { 197 goto invalid; 198 } 199 200 w = spdk_jsonrpc_begin_result(request); 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 217 if (spdk_json_decode_object(params, rpc_rename_lvol_store_decoders, 218 SPDK_COUNTOF(rpc_rename_lvol_store_decoders), 219 &req)) { 220 SPDK_INFOLOG(SPDK_LOG_LVOL_RPC, "spdk_json_decode_object failed\n"); 221 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 222 "spdk_json_decode_object failed"); 223 goto cleanup; 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 spdk_jsonrpc_send_error_response_fmt(request, -ENOENT, "Lvol store %s not found", req.old_name); 230 goto cleanup; 231 } 232 233 vbdev_lvs_rename(lvs, req.new_name, _spdk_rpc_rename_lvol_store_cb, request); 234 235 cleanup: 236 free_rpc_rename_lvol_store(&req); 237 } 238 SPDK_RPC_REGISTER("rename_lvol_store", spdk_rpc_rename_lvol_store, SPDK_RPC_RUNTIME) 239 240 struct rpc_destroy_lvol_store { 241 char *uuid; 242 char *lvs_name; 243 }; 244 245 static void 246 free_rpc_destroy_lvol_store(struct rpc_destroy_lvol_store *req) 247 { 248 free(req->uuid); 249 free(req->lvs_name); 250 } 251 252 static const struct spdk_json_object_decoder rpc_destroy_lvol_store_decoders[] = { 253 {"uuid", offsetof(struct rpc_destroy_lvol_store, uuid), spdk_json_decode_string, true}, 254 {"lvs_name", offsetof(struct rpc_destroy_lvol_store, lvs_name), spdk_json_decode_string, true}, 255 }; 256 257 static void 258 _spdk_rpc_lvol_store_destroy_cb(void *cb_arg, int lvserrno) 259 { 260 struct spdk_json_write_ctx *w; 261 struct spdk_jsonrpc_request *request = cb_arg; 262 263 if (lvserrno != 0) { 264 goto invalid; 265 } 266 267 w = spdk_jsonrpc_begin_result(request); 268 spdk_json_write_bool(w, true); 269 spdk_jsonrpc_end_result(request, w); 270 return; 271 272 invalid: 273 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 274 spdk_strerror(-lvserrno)); 275 } 276 277 static void 278 spdk_rpc_destroy_lvol_store(struct spdk_jsonrpc_request *request, 279 const struct spdk_json_val *params) 280 { 281 struct rpc_destroy_lvol_store req = {}; 282 struct spdk_lvol_store *lvs = NULL; 283 int rc; 284 285 if (spdk_json_decode_object(params, rpc_destroy_lvol_store_decoders, 286 SPDK_COUNTOF(rpc_destroy_lvol_store_decoders), 287 &req)) { 288 SPDK_INFOLOG(SPDK_LOG_LVOL_RPC, "spdk_json_decode_object failed\n"); 289 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 290 "spdk_json_decode_object failed"); 291 goto cleanup; 292 } 293 294 rc = vbdev_get_lvol_store_by_uuid_xor_name(req.uuid, req.lvs_name, &lvs); 295 if (rc != 0) { 296 spdk_jsonrpc_send_error_response(request, rc, spdk_strerror(-rc)); 297 goto cleanup; 298 } 299 300 vbdev_lvs_destruct(lvs, _spdk_rpc_lvol_store_destroy_cb, request); 301 302 cleanup: 303 free_rpc_destroy_lvol_store(&req); 304 } 305 SPDK_RPC_REGISTER("destroy_lvol_store", spdk_rpc_destroy_lvol_store, SPDK_RPC_RUNTIME) 306 307 struct rpc_construct_lvol_bdev { 308 char *uuid; 309 char *lvs_name; 310 char *lvol_name; 311 uint64_t size; 312 bool thin_provision; 313 char *clear_method; 314 }; 315 316 static void 317 free_rpc_construct_lvol_bdev(struct rpc_construct_lvol_bdev *req) 318 { 319 free(req->uuid); 320 free(req->lvs_name); 321 free(req->lvol_name); 322 free(req->clear_method); 323 } 324 325 static const struct spdk_json_object_decoder rpc_construct_lvol_bdev_decoders[] = { 326 {"uuid", offsetof(struct rpc_construct_lvol_bdev, uuid), spdk_json_decode_string, true}, 327 {"lvs_name", offsetof(struct rpc_construct_lvol_bdev, lvs_name), spdk_json_decode_string, true}, 328 {"lvol_name", offsetof(struct rpc_construct_lvol_bdev, lvol_name), spdk_json_decode_string}, 329 {"size", offsetof(struct rpc_construct_lvol_bdev, size), spdk_json_decode_uint64}, 330 {"thin_provision", offsetof(struct rpc_construct_lvol_bdev, thin_provision), spdk_json_decode_bool, true}, 331 {"clear_method", offsetof(struct rpc_construct_lvol_bdev, clear_method), spdk_json_decode_string, true}, 332 }; 333 334 static void 335 _spdk_rpc_construct_lvol_bdev_cb(void *cb_arg, struct spdk_lvol *lvol, int lvolerrno) 336 { 337 struct spdk_json_write_ctx *w; 338 struct spdk_jsonrpc_request *request = cb_arg; 339 340 if (lvolerrno != 0) { 341 goto invalid; 342 } 343 344 w = spdk_jsonrpc_begin_result(request); 345 spdk_json_write_string(w, lvol->unique_id); 346 spdk_jsonrpc_end_result(request, w); 347 return; 348 349 invalid: 350 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 351 spdk_strerror(-lvolerrno)); 352 } 353 354 static void 355 spdk_rpc_construct_lvol_bdev(struct spdk_jsonrpc_request *request, 356 const struct spdk_json_val *params) 357 { 358 struct rpc_construct_lvol_bdev req = {}; 359 enum lvol_clear_method clear_method; 360 int rc = 0; 361 struct spdk_lvol_store *lvs = NULL; 362 363 SPDK_INFOLOG(SPDK_LOG_LVOL_RPC, "Creating blob\n"); 364 365 if (spdk_json_decode_object(params, rpc_construct_lvol_bdev_decoders, 366 SPDK_COUNTOF(rpc_construct_lvol_bdev_decoders), 367 &req)) { 368 SPDK_INFOLOG(SPDK_LOG_LVOL_RPC, "spdk_json_decode_object failed\n"); 369 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 370 "spdk_json_decode_object failed"); 371 goto cleanup; 372 } 373 374 rc = vbdev_get_lvol_store_by_uuid_xor_name(req.uuid, req.lvs_name, &lvs); 375 if (rc != 0) { 376 spdk_jsonrpc_send_error_response(request, rc, spdk_strerror(-rc)); 377 goto cleanup; 378 } 379 380 if (req.clear_method != NULL) { 381 if (!strcasecmp(req.clear_method, "none")) { 382 clear_method = LVOL_CLEAR_WITH_NONE; 383 } else if (!strcasecmp(req.clear_method, "unmap")) { 384 clear_method = LVOL_CLEAR_WITH_UNMAP; 385 } else if (!strcasecmp(req.clear_method, "write_zeroes")) { 386 clear_method = LVOL_CLEAR_WITH_WRITE_ZEROES; 387 } else { 388 spdk_jsonrpc_send_error_response(request, -EINVAL, "Invalid clean_method option"); 389 goto cleanup; 390 } 391 } else { 392 clear_method = LVOL_CLEAR_WITH_DEFAULT; 393 } 394 395 rc = vbdev_lvol_create(lvs, req.lvol_name, req.size, req.thin_provision, 396 clear_method, _spdk_rpc_construct_lvol_bdev_cb, request); 397 if (rc < 0) { 398 spdk_jsonrpc_send_error_response(request, rc, spdk_strerror(-rc)); 399 goto cleanup; 400 } 401 402 cleanup: 403 free_rpc_construct_lvol_bdev(&req); 404 } 405 406 SPDK_RPC_REGISTER("construct_lvol_bdev", spdk_rpc_construct_lvol_bdev, SPDK_RPC_RUNTIME) 407 408 struct rpc_snapshot_lvol_bdev { 409 char *lvol_name; 410 char *snapshot_name; 411 }; 412 413 static void 414 free_rpc_snapshot_lvol_bdev(struct rpc_snapshot_lvol_bdev *req) 415 { 416 free(req->lvol_name); 417 free(req->snapshot_name); 418 } 419 420 static const struct spdk_json_object_decoder rpc_snapshot_lvol_bdev_decoders[] = { 421 {"lvol_name", offsetof(struct rpc_snapshot_lvol_bdev, lvol_name), spdk_json_decode_string}, 422 {"snapshot_name", offsetof(struct rpc_snapshot_lvol_bdev, snapshot_name), spdk_json_decode_string}, 423 }; 424 425 static void 426 _spdk_rpc_snapshot_lvol_bdev_cb(void *cb_arg, struct spdk_lvol *lvol, int lvolerrno) 427 { 428 struct spdk_json_write_ctx *w; 429 struct spdk_jsonrpc_request *request = cb_arg; 430 431 if (lvolerrno != 0) { 432 goto invalid; 433 } 434 435 w = spdk_jsonrpc_begin_result(request); 436 spdk_json_write_string(w, lvol->unique_id); 437 spdk_jsonrpc_end_result(request, w); 438 return; 439 440 invalid: 441 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 442 spdk_strerror(-lvolerrno)); 443 } 444 445 static void 446 spdk_rpc_snapshot_lvol_bdev(struct spdk_jsonrpc_request *request, 447 const struct spdk_json_val *params) 448 { 449 struct rpc_snapshot_lvol_bdev req = {}; 450 struct spdk_bdev *bdev; 451 struct spdk_lvol *lvol; 452 453 SPDK_INFOLOG(SPDK_LOG_LVOL_RPC, "Snapshotting blob\n"); 454 455 if (spdk_json_decode_object(params, rpc_snapshot_lvol_bdev_decoders, 456 SPDK_COUNTOF(rpc_snapshot_lvol_bdev_decoders), 457 &req)) { 458 SPDK_INFOLOG(SPDK_LOG_LVOL_RPC, "spdk_json_decode_object failed\n"); 459 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 460 "spdk_json_decode_object failed"); 461 goto cleanup; 462 } 463 464 bdev = spdk_bdev_get_by_name(req.lvol_name); 465 if (bdev == NULL) { 466 SPDK_INFOLOG(SPDK_LOG_LVOL_RPC, "bdev '%s' does not exist\n", req.lvol_name); 467 spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV)); 468 goto cleanup; 469 } 470 471 lvol = vbdev_lvol_get_from_bdev(bdev); 472 if (lvol == NULL) { 473 SPDK_ERRLOG("lvol does not exist\n"); 474 spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV)); 475 goto cleanup; 476 } 477 478 vbdev_lvol_create_snapshot(lvol, req.snapshot_name, _spdk_rpc_snapshot_lvol_bdev_cb, request); 479 480 cleanup: 481 free_rpc_snapshot_lvol_bdev(&req); 482 } 483 484 SPDK_RPC_REGISTER("snapshot_lvol_bdev", spdk_rpc_snapshot_lvol_bdev, SPDK_RPC_RUNTIME) 485 486 struct rpc_bdev_lvol_clone { 487 char *snapshot_name; 488 char *clone_name; 489 }; 490 491 static void 492 free_rpc_bdev_lvol_clone(struct rpc_bdev_lvol_clone *req) 493 { 494 free(req->snapshot_name); 495 free(req->clone_name); 496 } 497 498 static const struct spdk_json_object_decoder rpc_bdev_lvol_clone_decoders[] = { 499 {"snapshot_name", offsetof(struct rpc_bdev_lvol_clone, snapshot_name), spdk_json_decode_string}, 500 {"clone_name", offsetof(struct rpc_bdev_lvol_clone, clone_name), spdk_json_decode_string, true}, 501 }; 502 503 static void 504 _spdk_rpc_bdev_lvol_clone_cb(void *cb_arg, struct spdk_lvol *lvol, int lvolerrno) 505 { 506 struct spdk_json_write_ctx *w; 507 struct spdk_jsonrpc_request *request = cb_arg; 508 509 if (lvolerrno != 0) { 510 goto invalid; 511 } 512 513 w = spdk_jsonrpc_begin_result(request); 514 spdk_json_write_string(w, lvol->unique_id); 515 spdk_jsonrpc_end_result(request, w); 516 return; 517 518 invalid: 519 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 520 spdk_strerror(-lvolerrno)); 521 } 522 523 static void 524 spdk_rpc_bdev_lvol_clone(struct spdk_jsonrpc_request *request, 525 const struct spdk_json_val *params) 526 { 527 struct rpc_bdev_lvol_clone req = {}; 528 struct spdk_bdev *bdev; 529 struct spdk_lvol *lvol; 530 531 SPDK_INFOLOG(SPDK_LOG_LVOL_RPC, "Cloning blob\n"); 532 533 if (spdk_json_decode_object(params, rpc_bdev_lvol_clone_decoders, 534 SPDK_COUNTOF(rpc_bdev_lvol_clone_decoders), 535 &req)) { 536 SPDK_INFOLOG(SPDK_LOG_LVOL_RPC, "spdk_json_decode_object failed\n"); 537 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 538 "spdk_json_decode_object failed"); 539 goto cleanup; 540 } 541 542 bdev = spdk_bdev_get_by_name(req.snapshot_name); 543 if (bdev == NULL) { 544 SPDK_INFOLOG(SPDK_LOG_LVOL_RPC, "bdev '%s' does not exist\n", req.snapshot_name); 545 spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV)); 546 goto cleanup; 547 } 548 549 lvol = vbdev_lvol_get_from_bdev(bdev); 550 if (lvol == NULL) { 551 SPDK_ERRLOG("lvol does not exist\n"); 552 spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV)); 553 goto cleanup; 554 } 555 556 vbdev_lvol_create_clone(lvol, req.clone_name, _spdk_rpc_bdev_lvol_clone_cb, request); 557 558 cleanup: 559 free_rpc_bdev_lvol_clone(&req); 560 } 561 562 SPDK_RPC_REGISTER("bdev_lvol_clone", spdk_rpc_bdev_lvol_clone, SPDK_RPC_RUNTIME) 563 SPDK_RPC_REGISTER_ALIAS_DEPRECATED(bdev_lvol_clone, clone_lvol_bdev) 564 565 struct rpc_bdev_lvol_rename { 566 char *old_name; 567 char *new_name; 568 }; 569 570 static void 571 free_rpc_bdev_lvol_rename(struct rpc_bdev_lvol_rename *req) 572 { 573 free(req->old_name); 574 free(req->new_name); 575 } 576 577 static const struct spdk_json_object_decoder rpc_bdev_lvol_rename_decoders[] = { 578 {"old_name", offsetof(struct rpc_bdev_lvol_rename, old_name), spdk_json_decode_string}, 579 {"new_name", offsetof(struct rpc_bdev_lvol_rename, new_name), spdk_json_decode_string}, 580 }; 581 582 static void 583 _spdk_rpc_bdev_lvol_rename_cb(void *cb_arg, int lvolerrno) 584 { 585 struct spdk_json_write_ctx *w; 586 struct spdk_jsonrpc_request *request = cb_arg; 587 588 if (lvolerrno != 0) { 589 goto invalid; 590 } 591 592 w = spdk_jsonrpc_begin_result(request); 593 spdk_json_write_bool(w, true); 594 spdk_jsonrpc_end_result(request, w); 595 return; 596 597 invalid: 598 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 599 spdk_strerror(-lvolerrno)); 600 } 601 602 static void 603 spdk_rpc_bdev_lvol_rename(struct spdk_jsonrpc_request *request, 604 const struct spdk_json_val *params) 605 { 606 struct rpc_bdev_lvol_rename req = {}; 607 struct spdk_bdev *bdev; 608 struct spdk_lvol *lvol; 609 610 SPDK_INFOLOG(SPDK_LOG_LVOL_RPC, "Renaming lvol\n"); 611 612 if (spdk_json_decode_object(params, rpc_bdev_lvol_rename_decoders, 613 SPDK_COUNTOF(rpc_bdev_lvol_rename_decoders), 614 &req)) { 615 SPDK_INFOLOG(SPDK_LOG_LVOL_RPC, "spdk_json_decode_object failed\n"); 616 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 617 "spdk_json_decode_object failed"); 618 goto cleanup; 619 } 620 621 bdev = spdk_bdev_get_by_name(req.old_name); 622 if (bdev == NULL) { 623 SPDK_ERRLOG("bdev '%s' does not exist\n", req.old_name); 624 spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV)); 625 goto cleanup; 626 } 627 628 lvol = vbdev_lvol_get_from_bdev(bdev); 629 if (lvol == NULL) { 630 SPDK_ERRLOG("lvol does not exist\n"); 631 spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV)); 632 goto cleanup; 633 } 634 635 vbdev_lvol_rename(lvol, req.new_name, _spdk_rpc_bdev_lvol_rename_cb, request); 636 637 cleanup: 638 free_rpc_bdev_lvol_rename(&req); 639 } 640 641 SPDK_RPC_REGISTER("bdev_lvol_rename", spdk_rpc_bdev_lvol_rename, SPDK_RPC_RUNTIME) 642 SPDK_RPC_REGISTER_ALIAS_DEPRECATED(bdev_lvol_rename, rename_lvol_bdev) 643 644 struct rpc_inflate_lvol_bdev { 645 char *name; 646 }; 647 648 static void 649 free_rpc_inflate_lvol_bdev(struct rpc_inflate_lvol_bdev *req) 650 { 651 free(req->name); 652 } 653 654 static const struct spdk_json_object_decoder rpc_inflate_lvol_bdev_decoders[] = { 655 {"name", offsetof(struct rpc_inflate_lvol_bdev, name), spdk_json_decode_string}, 656 }; 657 658 static void 659 _spdk_rpc_inflate_lvol_bdev_cb(void *cb_arg, int lvolerrno) 660 { 661 struct spdk_json_write_ctx *w; 662 struct spdk_jsonrpc_request *request = cb_arg; 663 664 if (lvolerrno != 0) { 665 goto invalid; 666 } 667 668 w = spdk_jsonrpc_begin_result(request); 669 spdk_json_write_bool(w, true); 670 spdk_jsonrpc_end_result(request, w); 671 return; 672 673 invalid: 674 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 675 spdk_strerror(-lvolerrno)); 676 } 677 678 static void 679 spdk_rpc_inflate_lvol_bdev(struct spdk_jsonrpc_request *request, 680 const struct spdk_json_val *params) 681 { 682 struct rpc_inflate_lvol_bdev req = {}; 683 struct spdk_bdev *bdev; 684 struct spdk_lvol *lvol; 685 686 SPDK_INFOLOG(SPDK_LOG_LVOL_RPC, "Inflating lvol\n"); 687 688 if (spdk_json_decode_object(params, rpc_inflate_lvol_bdev_decoders, 689 SPDK_COUNTOF(rpc_inflate_lvol_bdev_decoders), 690 &req)) { 691 SPDK_INFOLOG(SPDK_LOG_LVOL_RPC, "spdk_json_decode_object failed\n"); 692 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 693 "spdk_json_decode_object failed"); 694 goto cleanup; 695 } 696 697 bdev = spdk_bdev_get_by_name(req.name); 698 if (bdev == NULL) { 699 SPDK_ERRLOG("bdev '%s' does not exist\n", req.name); 700 spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV)); 701 goto cleanup; 702 } 703 704 lvol = vbdev_lvol_get_from_bdev(bdev); 705 if (lvol == NULL) { 706 SPDK_ERRLOG("lvol does not exist\n"); 707 spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV)); 708 goto cleanup; 709 } 710 711 spdk_lvol_inflate(lvol, _spdk_rpc_inflate_lvol_bdev_cb, request); 712 713 cleanup: 714 free_rpc_inflate_lvol_bdev(&req); 715 } 716 717 SPDK_RPC_REGISTER("inflate_lvol_bdev", spdk_rpc_inflate_lvol_bdev, SPDK_RPC_RUNTIME) 718 719 static void 720 spdk_rpc_decouple_parent_lvol_bdev(struct spdk_jsonrpc_request *request, 721 const struct spdk_json_val *params) 722 { 723 struct rpc_inflate_lvol_bdev req = {}; 724 struct spdk_bdev *bdev; 725 struct spdk_lvol *lvol; 726 727 SPDK_INFOLOG(SPDK_LOG_LVOL_RPC, "Decoupling parent of lvol\n"); 728 729 if (spdk_json_decode_object(params, rpc_inflate_lvol_bdev_decoders, 730 SPDK_COUNTOF(rpc_inflate_lvol_bdev_decoders), 731 &req)) { 732 SPDK_INFOLOG(SPDK_LOG_LVOL_RPC, "spdk_json_decode_object failed\n"); 733 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 734 "spdk_json_decode_object failed"); 735 goto cleanup; 736 } 737 738 bdev = spdk_bdev_get_by_name(req.name); 739 if (bdev == NULL) { 740 SPDK_ERRLOG("bdev '%s' does not exist\n", req.name); 741 spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV)); 742 goto cleanup; 743 } 744 745 lvol = vbdev_lvol_get_from_bdev(bdev); 746 if (lvol == NULL) { 747 SPDK_ERRLOG("lvol does not exist\n"); 748 spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV)); 749 goto cleanup; 750 } 751 752 spdk_lvol_decouple_parent(lvol, _spdk_rpc_inflate_lvol_bdev_cb, request); 753 754 cleanup: 755 free_rpc_inflate_lvol_bdev(&req); 756 } 757 758 SPDK_RPC_REGISTER("decouple_parent_lvol_bdev", spdk_rpc_decouple_parent_lvol_bdev, SPDK_RPC_RUNTIME) 759 760 struct rpc_resize_lvol_bdev { 761 char *name; 762 uint64_t size; 763 }; 764 765 static void 766 free_rpc_resize_lvol_bdev(struct rpc_resize_lvol_bdev *req) 767 { 768 free(req->name); 769 } 770 771 static const struct spdk_json_object_decoder rpc_resize_lvol_bdev_decoders[] = { 772 {"name", offsetof(struct rpc_resize_lvol_bdev, name), spdk_json_decode_string}, 773 {"size", offsetof(struct rpc_resize_lvol_bdev, size), spdk_json_decode_uint64}, 774 }; 775 776 static void 777 _spdk_rpc_resize_lvol_bdev_cb(void *cb_arg, int lvolerrno) 778 { 779 struct spdk_json_write_ctx *w; 780 struct spdk_jsonrpc_request *request = cb_arg; 781 782 if (lvolerrno != 0) { 783 goto invalid; 784 } 785 786 w = spdk_jsonrpc_begin_result(request); 787 spdk_json_write_bool(w, true); 788 spdk_jsonrpc_end_result(request, w); 789 return; 790 791 invalid: 792 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 793 spdk_strerror(-lvolerrno)); 794 } 795 796 static void 797 spdk_rpc_resize_lvol_bdev(struct spdk_jsonrpc_request *request, 798 const struct spdk_json_val *params) 799 { 800 struct rpc_resize_lvol_bdev req = {}; 801 struct spdk_bdev *bdev; 802 struct spdk_lvol *lvol; 803 804 SPDK_INFOLOG(SPDK_LOG_LVOL_RPC, "Resizing lvol\n"); 805 806 if (spdk_json_decode_object(params, rpc_resize_lvol_bdev_decoders, 807 SPDK_COUNTOF(rpc_resize_lvol_bdev_decoders), 808 &req)) { 809 SPDK_INFOLOG(SPDK_LOG_LVOL_RPC, "spdk_json_decode_object failed\n"); 810 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 811 "spdk_json_decode_object failed"); 812 goto cleanup; 813 } 814 815 bdev = spdk_bdev_get_by_name(req.name); 816 if (bdev == NULL) { 817 SPDK_ERRLOG("no bdev for provided name %s\n", req.name); 818 spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV)); 819 goto cleanup; 820 } 821 822 lvol = vbdev_lvol_get_from_bdev(bdev); 823 if (lvol == NULL) { 824 spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV)); 825 goto cleanup; 826 } 827 828 vbdev_lvol_resize(lvol, req.size, _spdk_rpc_resize_lvol_bdev_cb, request); 829 830 cleanup: 831 free_rpc_resize_lvol_bdev(&req); 832 } 833 834 SPDK_RPC_REGISTER("resize_lvol_bdev", spdk_rpc_resize_lvol_bdev, SPDK_RPC_RUNTIME) 835 836 struct rpc_set_ro_lvol_bdev { 837 char *name; 838 }; 839 840 static void 841 free_rpc_set_ro_lvol_bdev(struct rpc_set_ro_lvol_bdev *req) 842 { 843 free(req->name); 844 } 845 846 static const struct spdk_json_object_decoder rpc_set_ro_lvol_bdev_decoders[] = { 847 {"name", offsetof(struct rpc_set_ro_lvol_bdev, name), spdk_json_decode_string}, 848 }; 849 850 static void 851 _spdk_rpc_set_ro_lvol_bdev_cb(void *cb_arg, int lvolerrno) 852 { 853 struct spdk_json_write_ctx *w; 854 struct spdk_jsonrpc_request *request = cb_arg; 855 856 if (lvolerrno != 0) { 857 goto invalid; 858 } 859 860 w = spdk_jsonrpc_begin_result(request); 861 spdk_json_write_bool(w, true); 862 spdk_jsonrpc_end_result(request, w); 863 return; 864 865 invalid: 866 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 867 spdk_strerror(-lvolerrno)); 868 } 869 870 static void 871 spdk_rpc_set_read_only_lvol_bdev(struct spdk_jsonrpc_request *request, 872 const struct spdk_json_val *params) 873 { 874 struct rpc_set_ro_lvol_bdev req = {}; 875 struct spdk_bdev *bdev; 876 struct spdk_lvol *lvol; 877 878 SPDK_INFOLOG(SPDK_LOG_LVOL_RPC, "Setting lvol as read only\n"); 879 880 if (spdk_json_decode_object(params, rpc_set_ro_lvol_bdev_decoders, 881 SPDK_COUNTOF(rpc_set_ro_lvol_bdev_decoders), 882 &req)) { 883 SPDK_INFOLOG(SPDK_LOG_LVOL_RPC, "spdk_json_decode_object failed\n"); 884 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 885 "spdk_json_decode_object failed"); 886 goto cleanup; 887 } 888 889 if (req.name == NULL) { 890 SPDK_ERRLOG("missing name param\n"); 891 spdk_jsonrpc_send_error_response(request, -EINVAL, "Missing name parameter"); 892 goto cleanup; 893 } 894 895 bdev = spdk_bdev_get_by_name(req.name); 896 if (bdev == NULL) { 897 SPDK_ERRLOG("no bdev for provided name %s\n", req.name); 898 spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV)); 899 goto cleanup; 900 } 901 902 lvol = vbdev_lvol_get_from_bdev(bdev); 903 if (lvol == NULL) { 904 spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV)); 905 goto cleanup; 906 } 907 908 vbdev_lvol_set_read_only(lvol, _spdk_rpc_set_ro_lvol_bdev_cb, request); 909 910 cleanup: 911 free_rpc_set_ro_lvol_bdev(&req); 912 } 913 914 SPDK_RPC_REGISTER("set_read_only_lvol_bdev", spdk_rpc_set_read_only_lvol_bdev, SPDK_RPC_RUNTIME) 915 916 struct rpc_destroy_lvol_bdev { 917 char *name; 918 }; 919 920 static void 921 free_rpc_destroy_lvol_bdev(struct rpc_destroy_lvol_bdev *req) 922 { 923 free(req->name); 924 } 925 926 static const struct spdk_json_object_decoder rpc_destroy_lvol_bdev_decoders[] = { 927 {"name", offsetof(struct rpc_destroy_lvol_bdev, name), spdk_json_decode_string}, 928 }; 929 930 static void 931 _spdk_rpc_destroy_lvol_bdev_cb(void *cb_arg, int lvolerrno) 932 { 933 struct spdk_json_write_ctx *w; 934 struct spdk_jsonrpc_request *request = cb_arg; 935 936 if (lvolerrno != 0) { 937 goto invalid; 938 } 939 940 w = spdk_jsonrpc_begin_result(request); 941 spdk_json_write_bool(w, true); 942 spdk_jsonrpc_end_result(request, w); 943 return; 944 945 invalid: 946 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 947 spdk_strerror(-lvolerrno)); 948 } 949 950 static void 951 spdk_rpc_destroy_lvol_bdev(struct spdk_jsonrpc_request *request, 952 const struct spdk_json_val *params) 953 { 954 struct rpc_destroy_lvol_bdev req = {}; 955 struct spdk_bdev *bdev; 956 struct spdk_lvol *lvol; 957 958 if (spdk_json_decode_object(params, rpc_destroy_lvol_bdev_decoders, 959 SPDK_COUNTOF(rpc_destroy_lvol_bdev_decoders), 960 &req)) { 961 SPDK_INFOLOG(SPDK_LOG_LVOL_RPC, "spdk_json_decode_object failed\n"); 962 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 963 "spdk_json_decode_object failed"); 964 goto cleanup; 965 } 966 967 bdev = spdk_bdev_get_by_name(req.name); 968 if (bdev == NULL) { 969 SPDK_ERRLOG("no bdev for provided name %s\n", req.name); 970 spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV)); 971 goto cleanup; 972 } 973 974 lvol = vbdev_lvol_get_from_bdev(bdev); 975 if (lvol == NULL) { 976 spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV)); 977 goto cleanup; 978 } 979 980 vbdev_lvol_destroy(lvol, _spdk_rpc_destroy_lvol_bdev_cb, request); 981 982 cleanup: 983 free_rpc_destroy_lvol_bdev(&req); 984 } 985 986 SPDK_RPC_REGISTER("destroy_lvol_bdev", spdk_rpc_destroy_lvol_bdev, SPDK_RPC_RUNTIME) 987 988 struct rpc_bdev_lvol_get_lvstores { 989 char *uuid; 990 char *lvs_name; 991 }; 992 993 static void 994 free_rpc_bdev_lvol_get_lvstores(struct rpc_bdev_lvol_get_lvstores *req) 995 { 996 free(req->uuid); 997 free(req->lvs_name); 998 } 999 1000 static const struct spdk_json_object_decoder rpc_bdev_lvol_get_lvstores_decoders[] = { 1001 {"uuid", offsetof(struct rpc_bdev_lvol_get_lvstores, uuid), spdk_json_decode_string, true}, 1002 {"lvs_name", offsetof(struct rpc_bdev_lvol_get_lvstores, lvs_name), spdk_json_decode_string, true}, 1003 }; 1004 1005 static void 1006 spdk_rpc_dump_lvol_store_info(struct spdk_json_write_ctx *w, struct lvol_store_bdev *lvs_bdev) 1007 { 1008 struct spdk_blob_store *bs; 1009 uint64_t cluster_size, block_size; 1010 char uuid[SPDK_UUID_STRING_LEN]; 1011 1012 bs = lvs_bdev->lvs->blobstore; 1013 cluster_size = spdk_bs_get_cluster_size(bs); 1014 /* Block size of lvols is always size of blob store page */ 1015 block_size = spdk_bs_get_page_size(bs); 1016 1017 spdk_json_write_object_begin(w); 1018 1019 spdk_uuid_fmt_lower(uuid, sizeof(uuid), &lvs_bdev->lvs->uuid); 1020 spdk_json_write_named_string(w, "uuid", uuid); 1021 1022 spdk_json_write_named_string(w, "name", lvs_bdev->lvs->name); 1023 1024 spdk_json_write_named_string(w, "base_bdev", spdk_bdev_get_name(lvs_bdev->bdev)); 1025 1026 spdk_json_write_named_uint64(w, "total_data_clusters", spdk_bs_total_data_cluster_count(bs)); 1027 1028 spdk_json_write_named_uint64(w, "free_clusters", spdk_bs_free_cluster_count(bs)); 1029 1030 spdk_json_write_named_uint64(w, "block_size", block_size); 1031 1032 spdk_json_write_named_uint64(w, "cluster_size", cluster_size); 1033 1034 spdk_json_write_object_end(w); 1035 } 1036 1037 static void 1038 spdk_rpc_bdev_lvol_get_lvstores(struct spdk_jsonrpc_request *request, 1039 const struct spdk_json_val *params) 1040 { 1041 struct rpc_bdev_lvol_get_lvstores req = {}; 1042 struct spdk_json_write_ctx *w; 1043 struct lvol_store_bdev *lvs_bdev = NULL; 1044 struct spdk_lvol_store *lvs = NULL; 1045 int rc; 1046 1047 if (params != NULL) { 1048 if (spdk_json_decode_object(params, rpc_bdev_lvol_get_lvstores_decoders, 1049 SPDK_COUNTOF(rpc_bdev_lvol_get_lvstores_decoders), 1050 &req)) { 1051 SPDK_INFOLOG(SPDK_LOG_LVOL_RPC, "spdk_json_decode_object failed\n"); 1052 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 1053 "spdk_json_decode_object failed"); 1054 goto cleanup; 1055 } 1056 1057 rc = vbdev_get_lvol_store_by_uuid_xor_name(req.uuid, req.lvs_name, &lvs); 1058 if (rc != 0) { 1059 spdk_jsonrpc_send_error_response(request, rc, spdk_strerror(-rc)); 1060 goto cleanup; 1061 } 1062 1063 lvs_bdev = vbdev_get_lvs_bdev_by_lvs(lvs); 1064 if (lvs_bdev == NULL) { 1065 spdk_jsonrpc_send_error_response(request, ENODEV, spdk_strerror(-ENODEV)); 1066 goto cleanup; 1067 } 1068 } 1069 1070 w = spdk_jsonrpc_begin_result(request); 1071 spdk_json_write_array_begin(w); 1072 1073 if (lvs_bdev != NULL) { 1074 spdk_rpc_dump_lvol_store_info(w, lvs_bdev); 1075 } else { 1076 for (lvs_bdev = vbdev_lvol_store_first(); lvs_bdev != NULL; 1077 lvs_bdev = vbdev_lvol_store_next(lvs_bdev)) { 1078 spdk_rpc_dump_lvol_store_info(w, lvs_bdev); 1079 } 1080 } 1081 spdk_json_write_array_end(w); 1082 1083 spdk_jsonrpc_end_result(request, w); 1084 1085 cleanup: 1086 free_rpc_bdev_lvol_get_lvstores(&req); 1087 } 1088 1089 SPDK_RPC_REGISTER("bdev_lvol_get_lvstores", spdk_rpc_bdev_lvol_get_lvstores, SPDK_RPC_RUNTIME) 1090 SPDK_RPC_REGISTER_ALIAS_DEPRECATED(bdev_lvol_get_lvstores, get_lvol_stores) 1091