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