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