1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright (C) 2017 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 uint64_t size_in_mib; 273 bool thin_provision; 274 char *clear_method; 275 }; 276 277 static void 278 free_rpc_bdev_lvol_create(struct rpc_bdev_lvol_create *req) 279 { 280 free(req->uuid); 281 free(req->lvs_name); 282 free(req->lvol_name); 283 free(req->clear_method); 284 } 285 286 static const struct spdk_json_object_decoder rpc_bdev_lvol_create_decoders[] = { 287 {"uuid", offsetof(struct rpc_bdev_lvol_create, uuid), spdk_json_decode_string, true}, 288 {"lvs_name", offsetof(struct rpc_bdev_lvol_create, lvs_name), spdk_json_decode_string, true}, 289 {"lvol_name", offsetof(struct rpc_bdev_lvol_create, lvol_name), spdk_json_decode_string}, 290 {"size", offsetof(struct rpc_bdev_lvol_create, size), spdk_json_decode_uint64, true}, 291 {"size_in_mib", offsetof(struct rpc_bdev_lvol_create, size_in_mib), spdk_json_decode_uint64, true}, 292 {"thin_provision", offsetof(struct rpc_bdev_lvol_create, thin_provision), spdk_json_decode_bool, true}, 293 {"clear_method", offsetof(struct rpc_bdev_lvol_create, clear_method), spdk_json_decode_string, true}, 294 }; 295 296 static void 297 rpc_bdev_lvol_create_cb(void *cb_arg, struct spdk_lvol *lvol, int lvolerrno) 298 { 299 struct spdk_json_write_ctx *w; 300 struct spdk_jsonrpc_request *request = cb_arg; 301 302 if (lvolerrno != 0) { 303 goto invalid; 304 } 305 306 w = spdk_jsonrpc_begin_result(request); 307 spdk_json_write_string(w, lvol->unique_id); 308 spdk_jsonrpc_end_result(request, w); 309 return; 310 311 invalid: 312 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 313 spdk_strerror(-lvolerrno)); 314 } 315 316 SPDK_LOG_DEPRECATION_REGISTER(vbdev_lvol_rpc_req_size, 317 "rpc_bdev_lvol_create/resize req.size", 318 "v23.09", 0); 319 320 static void 321 rpc_bdev_lvol_create(struct spdk_jsonrpc_request *request, 322 const struct spdk_json_val *params) 323 { 324 struct rpc_bdev_lvol_create req = {}; 325 enum lvol_clear_method clear_method; 326 int rc = 0; 327 struct spdk_lvol_store *lvs = NULL; 328 uint64_t size = 0; 329 330 SPDK_INFOLOG(lvol_rpc, "Creating blob\n"); 331 332 if (spdk_json_decode_object(params, rpc_bdev_lvol_create_decoders, 333 SPDK_COUNTOF(rpc_bdev_lvol_create_decoders), 334 &req)) { 335 SPDK_INFOLOG(lvol_rpc, "spdk_json_decode_object failed\n"); 336 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 337 "spdk_json_decode_object failed"); 338 goto cleanup; 339 } 340 341 if (req.size > 0 && req.size_in_mib > 0) { 342 SPDK_LOG_DEPRECATED(vbdev_lvol_rpc_req_size); 343 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 344 "size is deprecated. Specify only size_in_mib instead."); 345 goto cleanup; 346 } else if (req.size_in_mib > 0) { 347 size = req.size_in_mib * 1024 * 1024; 348 } else { 349 SPDK_LOG_DEPRECATED(vbdev_lvol_rpc_req_size); 350 size = req.size; 351 } 352 353 rc = vbdev_get_lvol_store_by_uuid_xor_name(req.uuid, req.lvs_name, &lvs); 354 if (rc != 0) { 355 spdk_jsonrpc_send_error_response(request, rc, spdk_strerror(-rc)); 356 goto cleanup; 357 } 358 359 if (req.clear_method != NULL) { 360 if (!strcasecmp(req.clear_method, "none")) { 361 clear_method = LVOL_CLEAR_WITH_NONE; 362 } else if (!strcasecmp(req.clear_method, "unmap")) { 363 clear_method = LVOL_CLEAR_WITH_UNMAP; 364 } else if (!strcasecmp(req.clear_method, "write_zeroes")) { 365 clear_method = LVOL_CLEAR_WITH_WRITE_ZEROES; 366 } else { 367 spdk_jsonrpc_send_error_response(request, -EINVAL, "Invalid clean_method option"); 368 goto cleanup; 369 } 370 } else { 371 clear_method = LVOL_CLEAR_WITH_DEFAULT; 372 } 373 374 rc = vbdev_lvol_create(lvs, req.lvol_name, size, req.thin_provision, 375 clear_method, rpc_bdev_lvol_create_cb, request); 376 if (rc < 0) { 377 spdk_jsonrpc_send_error_response(request, rc, spdk_strerror(-rc)); 378 goto cleanup; 379 } 380 381 cleanup: 382 free_rpc_bdev_lvol_create(&req); 383 } 384 385 SPDK_RPC_REGISTER("bdev_lvol_create", rpc_bdev_lvol_create, SPDK_RPC_RUNTIME) 386 387 struct rpc_bdev_lvol_snapshot { 388 char *lvol_name; 389 char *snapshot_name; 390 }; 391 392 static void 393 free_rpc_bdev_lvol_snapshot(struct rpc_bdev_lvol_snapshot *req) 394 { 395 free(req->lvol_name); 396 free(req->snapshot_name); 397 } 398 399 static const struct spdk_json_object_decoder rpc_bdev_lvol_snapshot_decoders[] = { 400 {"lvol_name", offsetof(struct rpc_bdev_lvol_snapshot, lvol_name), spdk_json_decode_string}, 401 {"snapshot_name", offsetof(struct rpc_bdev_lvol_snapshot, snapshot_name), spdk_json_decode_string}, 402 }; 403 404 static void 405 rpc_bdev_lvol_snapshot_cb(void *cb_arg, struct spdk_lvol *lvol, int lvolerrno) 406 { 407 struct spdk_json_write_ctx *w; 408 struct spdk_jsonrpc_request *request = cb_arg; 409 410 if (lvolerrno != 0) { 411 goto invalid; 412 } 413 414 w = spdk_jsonrpc_begin_result(request); 415 spdk_json_write_string(w, lvol->unique_id); 416 spdk_jsonrpc_end_result(request, w); 417 return; 418 419 invalid: 420 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 421 spdk_strerror(-lvolerrno)); 422 } 423 424 static void 425 rpc_bdev_lvol_snapshot(struct spdk_jsonrpc_request *request, 426 const struct spdk_json_val *params) 427 { 428 struct rpc_bdev_lvol_snapshot req = {}; 429 struct spdk_bdev *bdev; 430 struct spdk_lvol *lvol; 431 432 SPDK_INFOLOG(lvol_rpc, "Snapshotting blob\n"); 433 434 if (spdk_json_decode_object(params, rpc_bdev_lvol_snapshot_decoders, 435 SPDK_COUNTOF(rpc_bdev_lvol_snapshot_decoders), 436 &req)) { 437 SPDK_INFOLOG(lvol_rpc, "spdk_json_decode_object failed\n"); 438 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 439 "spdk_json_decode_object failed"); 440 goto cleanup; 441 } 442 443 bdev = spdk_bdev_get_by_name(req.lvol_name); 444 if (bdev == NULL) { 445 SPDK_INFOLOG(lvol_rpc, "bdev '%s' does not exist\n", req.lvol_name); 446 spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV)); 447 goto cleanup; 448 } 449 450 lvol = vbdev_lvol_get_from_bdev(bdev); 451 if (lvol == NULL) { 452 SPDK_ERRLOG("lvol does not exist\n"); 453 spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV)); 454 goto cleanup; 455 } 456 457 vbdev_lvol_create_snapshot(lvol, req.snapshot_name, rpc_bdev_lvol_snapshot_cb, request); 458 459 cleanup: 460 free_rpc_bdev_lvol_snapshot(&req); 461 } 462 463 SPDK_RPC_REGISTER("bdev_lvol_snapshot", rpc_bdev_lvol_snapshot, SPDK_RPC_RUNTIME) 464 465 struct rpc_bdev_lvol_clone { 466 char *snapshot_name; 467 char *clone_name; 468 }; 469 470 static void 471 free_rpc_bdev_lvol_clone(struct rpc_bdev_lvol_clone *req) 472 { 473 free(req->snapshot_name); 474 free(req->clone_name); 475 } 476 477 static const struct spdk_json_object_decoder rpc_bdev_lvol_clone_decoders[] = { 478 {"snapshot_name", offsetof(struct rpc_bdev_lvol_clone, snapshot_name), spdk_json_decode_string}, 479 {"clone_name", offsetof(struct rpc_bdev_lvol_clone, clone_name), spdk_json_decode_string, true}, 480 }; 481 482 static void 483 rpc_bdev_lvol_clone_cb(void *cb_arg, struct spdk_lvol *lvol, int lvolerrno) 484 { 485 struct spdk_json_write_ctx *w; 486 struct spdk_jsonrpc_request *request = cb_arg; 487 488 if (lvolerrno != 0) { 489 goto invalid; 490 } 491 492 w = spdk_jsonrpc_begin_result(request); 493 spdk_json_write_string(w, lvol->unique_id); 494 spdk_jsonrpc_end_result(request, w); 495 return; 496 497 invalid: 498 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 499 spdk_strerror(-lvolerrno)); 500 } 501 502 static void 503 rpc_bdev_lvol_clone(struct spdk_jsonrpc_request *request, 504 const struct spdk_json_val *params) 505 { 506 struct rpc_bdev_lvol_clone req = {}; 507 struct spdk_bdev *bdev; 508 struct spdk_lvol *lvol; 509 510 SPDK_INFOLOG(lvol_rpc, "Cloning blob\n"); 511 512 if (spdk_json_decode_object(params, rpc_bdev_lvol_clone_decoders, 513 SPDK_COUNTOF(rpc_bdev_lvol_clone_decoders), 514 &req)) { 515 SPDK_INFOLOG(lvol_rpc, "spdk_json_decode_object failed\n"); 516 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 517 "spdk_json_decode_object failed"); 518 goto cleanup; 519 } 520 521 bdev = spdk_bdev_get_by_name(req.snapshot_name); 522 if (bdev == NULL) { 523 SPDK_INFOLOG(lvol_rpc, "bdev '%s' does not exist\n", req.snapshot_name); 524 spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV)); 525 goto cleanup; 526 } 527 528 lvol = vbdev_lvol_get_from_bdev(bdev); 529 if (lvol == NULL) { 530 SPDK_ERRLOG("lvol does not exist\n"); 531 spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV)); 532 goto cleanup; 533 } 534 535 vbdev_lvol_create_clone(lvol, req.clone_name, rpc_bdev_lvol_clone_cb, request); 536 537 cleanup: 538 free_rpc_bdev_lvol_clone(&req); 539 } 540 541 SPDK_RPC_REGISTER("bdev_lvol_clone", rpc_bdev_lvol_clone, SPDK_RPC_RUNTIME) 542 543 struct rpc_bdev_lvol_rename { 544 char *old_name; 545 char *new_name; 546 }; 547 548 static void 549 free_rpc_bdev_lvol_rename(struct rpc_bdev_lvol_rename *req) 550 { 551 free(req->old_name); 552 free(req->new_name); 553 } 554 555 static const struct spdk_json_object_decoder rpc_bdev_lvol_rename_decoders[] = { 556 {"old_name", offsetof(struct rpc_bdev_lvol_rename, old_name), spdk_json_decode_string}, 557 {"new_name", offsetof(struct rpc_bdev_lvol_rename, new_name), spdk_json_decode_string}, 558 }; 559 560 static void 561 rpc_bdev_lvol_rename_cb(void *cb_arg, int lvolerrno) 562 { 563 struct spdk_jsonrpc_request *request = cb_arg; 564 565 if (lvolerrno != 0) { 566 goto invalid; 567 } 568 569 spdk_jsonrpc_send_bool_response(request, true); 570 return; 571 572 invalid: 573 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 574 spdk_strerror(-lvolerrno)); 575 } 576 577 static void 578 rpc_bdev_lvol_rename(struct spdk_jsonrpc_request *request, 579 const struct spdk_json_val *params) 580 { 581 struct rpc_bdev_lvol_rename req = {}; 582 struct spdk_bdev *bdev; 583 struct spdk_lvol *lvol; 584 585 SPDK_INFOLOG(lvol_rpc, "Renaming lvol\n"); 586 587 if (spdk_json_decode_object(params, rpc_bdev_lvol_rename_decoders, 588 SPDK_COUNTOF(rpc_bdev_lvol_rename_decoders), 589 &req)) { 590 SPDK_INFOLOG(lvol_rpc, "spdk_json_decode_object failed\n"); 591 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 592 "spdk_json_decode_object failed"); 593 goto cleanup; 594 } 595 596 bdev = spdk_bdev_get_by_name(req.old_name); 597 if (bdev == NULL) { 598 SPDK_ERRLOG("bdev '%s' does not exist\n", req.old_name); 599 spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV)); 600 goto cleanup; 601 } 602 603 lvol = vbdev_lvol_get_from_bdev(bdev); 604 if (lvol == NULL) { 605 SPDK_ERRLOG("lvol does not exist\n"); 606 spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV)); 607 goto cleanup; 608 } 609 610 vbdev_lvol_rename(lvol, req.new_name, rpc_bdev_lvol_rename_cb, request); 611 612 cleanup: 613 free_rpc_bdev_lvol_rename(&req); 614 } 615 616 SPDK_RPC_REGISTER("bdev_lvol_rename", rpc_bdev_lvol_rename, SPDK_RPC_RUNTIME) 617 618 struct rpc_bdev_lvol_inflate { 619 char *name; 620 }; 621 622 static void 623 free_rpc_bdev_lvol_inflate(struct rpc_bdev_lvol_inflate *req) 624 { 625 free(req->name); 626 } 627 628 static const struct spdk_json_object_decoder rpc_bdev_lvol_inflate_decoders[] = { 629 {"name", offsetof(struct rpc_bdev_lvol_inflate, name), spdk_json_decode_string}, 630 }; 631 632 static void 633 rpc_bdev_lvol_inflate_cb(void *cb_arg, int lvolerrno) 634 { 635 struct spdk_jsonrpc_request *request = cb_arg; 636 637 if (lvolerrno != 0) { 638 goto invalid; 639 } 640 641 spdk_jsonrpc_send_bool_response(request, true); 642 return; 643 644 invalid: 645 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 646 spdk_strerror(-lvolerrno)); 647 } 648 649 static void 650 rpc_bdev_lvol_inflate(struct spdk_jsonrpc_request *request, 651 const struct spdk_json_val *params) 652 { 653 struct rpc_bdev_lvol_inflate req = {}; 654 struct spdk_bdev *bdev; 655 struct spdk_lvol *lvol; 656 657 SPDK_INFOLOG(lvol_rpc, "Inflating lvol\n"); 658 659 if (spdk_json_decode_object(params, rpc_bdev_lvol_inflate_decoders, 660 SPDK_COUNTOF(rpc_bdev_lvol_inflate_decoders), 661 &req)) { 662 SPDK_INFOLOG(lvol_rpc, "spdk_json_decode_object failed\n"); 663 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 664 "spdk_json_decode_object failed"); 665 goto cleanup; 666 } 667 668 bdev = spdk_bdev_get_by_name(req.name); 669 if (bdev == NULL) { 670 SPDK_ERRLOG("bdev '%s' does not exist\n", req.name); 671 spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV)); 672 goto cleanup; 673 } 674 675 lvol = vbdev_lvol_get_from_bdev(bdev); 676 if (lvol == NULL) { 677 SPDK_ERRLOG("lvol does not exist\n"); 678 spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV)); 679 goto cleanup; 680 } 681 682 spdk_lvol_inflate(lvol, rpc_bdev_lvol_inflate_cb, request); 683 684 cleanup: 685 free_rpc_bdev_lvol_inflate(&req); 686 } 687 688 SPDK_RPC_REGISTER("bdev_lvol_inflate", rpc_bdev_lvol_inflate, SPDK_RPC_RUNTIME) 689 690 static void 691 rpc_bdev_lvol_decouple_parent(struct spdk_jsonrpc_request *request, 692 const struct spdk_json_val *params) 693 { 694 struct rpc_bdev_lvol_inflate req = {}; 695 struct spdk_bdev *bdev; 696 struct spdk_lvol *lvol; 697 698 SPDK_INFOLOG(lvol_rpc, "Decoupling parent of lvol\n"); 699 700 if (spdk_json_decode_object(params, rpc_bdev_lvol_inflate_decoders, 701 SPDK_COUNTOF(rpc_bdev_lvol_inflate_decoders), 702 &req)) { 703 SPDK_INFOLOG(lvol_rpc, "spdk_json_decode_object failed\n"); 704 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 705 "spdk_json_decode_object failed"); 706 goto cleanup; 707 } 708 709 bdev = spdk_bdev_get_by_name(req.name); 710 if (bdev == NULL) { 711 SPDK_ERRLOG("bdev '%s' does not exist\n", req.name); 712 spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV)); 713 goto cleanup; 714 } 715 716 lvol = vbdev_lvol_get_from_bdev(bdev); 717 if (lvol == NULL) { 718 SPDK_ERRLOG("lvol does not exist\n"); 719 spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV)); 720 goto cleanup; 721 } 722 723 spdk_lvol_decouple_parent(lvol, rpc_bdev_lvol_inflate_cb, request); 724 725 cleanup: 726 free_rpc_bdev_lvol_inflate(&req); 727 } 728 729 SPDK_RPC_REGISTER("bdev_lvol_decouple_parent", rpc_bdev_lvol_decouple_parent, SPDK_RPC_RUNTIME) 730 731 struct rpc_bdev_lvol_resize { 732 char *name; 733 uint64_t size; 734 uint64_t size_in_mib; 735 }; 736 737 static void 738 free_rpc_bdev_lvol_resize(struct rpc_bdev_lvol_resize *req) 739 { 740 free(req->name); 741 } 742 743 static const struct spdk_json_object_decoder rpc_bdev_lvol_resize_decoders[] = { 744 {"name", offsetof(struct rpc_bdev_lvol_resize, name), spdk_json_decode_string}, 745 {"size", offsetof(struct rpc_bdev_lvol_resize, size), spdk_json_decode_uint64, true}, 746 {"size_in_mib", offsetof(struct rpc_bdev_lvol_resize, size_in_mib), spdk_json_decode_uint64, true}, 747 }; 748 749 static void 750 rpc_bdev_lvol_resize_cb(void *cb_arg, int lvolerrno) 751 { 752 struct spdk_jsonrpc_request *request = cb_arg; 753 754 if (lvolerrno != 0) { 755 goto invalid; 756 } 757 758 spdk_jsonrpc_send_bool_response(request, true); 759 return; 760 761 invalid: 762 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 763 spdk_strerror(-lvolerrno)); 764 } 765 766 static void 767 rpc_bdev_lvol_resize(struct spdk_jsonrpc_request *request, 768 const struct spdk_json_val *params) 769 { 770 struct rpc_bdev_lvol_resize req = {}; 771 struct spdk_bdev *bdev; 772 struct spdk_lvol *lvol; 773 uint64_t size = 0; 774 775 SPDK_INFOLOG(lvol_rpc, "Resizing lvol\n"); 776 777 if (spdk_json_decode_object(params, rpc_bdev_lvol_resize_decoders, 778 SPDK_COUNTOF(rpc_bdev_lvol_resize_decoders), 779 &req)) { 780 SPDK_INFOLOG(lvol_rpc, "spdk_json_decode_object failed\n"); 781 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 782 "spdk_json_decode_object failed"); 783 goto cleanup; 784 } 785 786 if (req.size > 0 && req.size_in_mib > 0) { 787 SPDK_LOG_DEPRECATED(vbdev_lvol_rpc_req_size); 788 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 789 "size is deprecated. Specify only size_in_mib instead."); 790 goto cleanup; 791 } else if (req.size_in_mib > 0) { 792 size = req.size_in_mib * 1024 * 1024; 793 } else { 794 SPDK_LOG_DEPRECATED(vbdev_lvol_rpc_req_size); 795 size = req.size; 796 } 797 798 bdev = spdk_bdev_get_by_name(req.name); 799 if (bdev == NULL) { 800 SPDK_ERRLOG("no bdev for provided name %s\n", req.name); 801 spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV)); 802 goto cleanup; 803 } 804 805 lvol = vbdev_lvol_get_from_bdev(bdev); 806 if (lvol == NULL) { 807 spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV)); 808 goto cleanup; 809 } 810 811 812 vbdev_lvol_resize(lvol, 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 820 struct rpc_set_ro_lvol_bdev { 821 char *name; 822 }; 823 824 static void 825 free_rpc_set_ro_lvol_bdev(struct rpc_set_ro_lvol_bdev *req) 826 { 827 free(req->name); 828 } 829 830 static const struct spdk_json_object_decoder rpc_set_ro_lvol_bdev_decoders[] = { 831 {"name", offsetof(struct rpc_set_ro_lvol_bdev, name), spdk_json_decode_string}, 832 }; 833 834 static void 835 rpc_set_ro_lvol_bdev_cb(void *cb_arg, int lvolerrno) 836 { 837 struct spdk_jsonrpc_request *request = cb_arg; 838 839 if (lvolerrno != 0) { 840 goto invalid; 841 } 842 843 spdk_jsonrpc_send_bool_response(request, true); 844 return; 845 846 invalid: 847 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 848 spdk_strerror(-lvolerrno)); 849 } 850 851 static void 852 rpc_bdev_lvol_set_read_only(struct spdk_jsonrpc_request *request, 853 const struct spdk_json_val *params) 854 { 855 struct rpc_set_ro_lvol_bdev req = {}; 856 struct spdk_bdev *bdev; 857 struct spdk_lvol *lvol; 858 859 SPDK_INFOLOG(lvol_rpc, "Setting lvol as read only\n"); 860 861 if (spdk_json_decode_object(params, rpc_set_ro_lvol_bdev_decoders, 862 SPDK_COUNTOF(rpc_set_ro_lvol_bdev_decoders), 863 &req)) { 864 SPDK_INFOLOG(lvol_rpc, "spdk_json_decode_object failed\n"); 865 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 866 "spdk_json_decode_object failed"); 867 goto cleanup; 868 } 869 870 if (req.name == NULL) { 871 SPDK_ERRLOG("missing name param\n"); 872 spdk_jsonrpc_send_error_response(request, -EINVAL, "Missing name parameter"); 873 goto cleanup; 874 } 875 876 bdev = spdk_bdev_get_by_name(req.name); 877 if (bdev == NULL) { 878 SPDK_ERRLOG("no bdev for provided name %s\n", req.name); 879 spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV)); 880 goto cleanup; 881 } 882 883 lvol = vbdev_lvol_get_from_bdev(bdev); 884 if (lvol == NULL) { 885 spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV)); 886 goto cleanup; 887 } 888 889 vbdev_lvol_set_read_only(lvol, rpc_set_ro_lvol_bdev_cb, request); 890 891 cleanup: 892 free_rpc_set_ro_lvol_bdev(&req); 893 } 894 895 SPDK_RPC_REGISTER("bdev_lvol_set_read_only", rpc_bdev_lvol_set_read_only, SPDK_RPC_RUNTIME) 896 897 struct rpc_bdev_lvol_delete { 898 char *name; 899 }; 900 901 static void 902 free_rpc_bdev_lvol_delete(struct rpc_bdev_lvol_delete *req) 903 { 904 free(req->name); 905 } 906 907 static const struct spdk_json_object_decoder rpc_bdev_lvol_delete_decoders[] = { 908 {"name", offsetof(struct rpc_bdev_lvol_delete, name), spdk_json_decode_string}, 909 }; 910 911 static void 912 rpc_bdev_lvol_delete_cb(void *cb_arg, int lvolerrno) 913 { 914 struct spdk_jsonrpc_request *request = cb_arg; 915 916 if (lvolerrno != 0) { 917 goto invalid; 918 } 919 920 spdk_jsonrpc_send_bool_response(request, true); 921 return; 922 923 invalid: 924 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 925 spdk_strerror(-lvolerrno)); 926 } 927 928 static void 929 rpc_bdev_lvol_delete(struct spdk_jsonrpc_request *request, 930 const struct spdk_json_val *params) 931 { 932 struct rpc_bdev_lvol_delete req = {}; 933 struct spdk_bdev *bdev; 934 struct spdk_lvol *lvol; 935 936 if (spdk_json_decode_object(params, rpc_bdev_lvol_delete_decoders, 937 SPDK_COUNTOF(rpc_bdev_lvol_delete_decoders), 938 &req)) { 939 SPDK_INFOLOG(lvol_rpc, "spdk_json_decode_object failed\n"); 940 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 941 "spdk_json_decode_object failed"); 942 goto cleanup; 943 } 944 945 bdev = spdk_bdev_get_by_name(req.name); 946 if (bdev == NULL) { 947 SPDK_ERRLOG("no bdev for provided name %s\n", req.name); 948 spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV)); 949 goto cleanup; 950 } 951 952 lvol = vbdev_lvol_get_from_bdev(bdev); 953 if (lvol == NULL) { 954 spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV)); 955 goto cleanup; 956 } 957 958 vbdev_lvol_destroy(lvol, rpc_bdev_lvol_delete_cb, request); 959 960 cleanup: 961 free_rpc_bdev_lvol_delete(&req); 962 } 963 964 SPDK_RPC_REGISTER("bdev_lvol_delete", rpc_bdev_lvol_delete, SPDK_RPC_RUNTIME) 965 966 struct rpc_bdev_lvol_get_lvstores { 967 char *uuid; 968 char *lvs_name; 969 }; 970 971 static void 972 free_rpc_bdev_lvol_get_lvstores(struct rpc_bdev_lvol_get_lvstores *req) 973 { 974 free(req->uuid); 975 free(req->lvs_name); 976 } 977 978 static const struct spdk_json_object_decoder rpc_bdev_lvol_get_lvstores_decoders[] = { 979 {"uuid", offsetof(struct rpc_bdev_lvol_get_lvstores, uuid), spdk_json_decode_string, true}, 980 {"lvs_name", offsetof(struct rpc_bdev_lvol_get_lvstores, lvs_name), spdk_json_decode_string, true}, 981 }; 982 983 static void 984 rpc_dump_lvol_store_info(struct spdk_json_write_ctx *w, struct lvol_store_bdev *lvs_bdev) 985 { 986 struct spdk_blob_store *bs; 987 uint64_t cluster_size; 988 char uuid[SPDK_UUID_STRING_LEN]; 989 990 bs = lvs_bdev->lvs->blobstore; 991 cluster_size = spdk_bs_get_cluster_size(bs); 992 993 spdk_json_write_object_begin(w); 994 995 spdk_uuid_fmt_lower(uuid, sizeof(uuid), &lvs_bdev->lvs->uuid); 996 spdk_json_write_named_string(w, "uuid", uuid); 997 998 spdk_json_write_named_string(w, "name", lvs_bdev->lvs->name); 999 1000 spdk_json_write_named_string(w, "base_bdev", spdk_bdev_get_name(lvs_bdev->bdev)); 1001 1002 spdk_json_write_named_uint64(w, "total_data_clusters", spdk_bs_total_data_cluster_count(bs)); 1003 1004 spdk_json_write_named_uint64(w, "free_clusters", spdk_bs_free_cluster_count(bs)); 1005 1006 spdk_json_write_named_uint64(w, "block_size", spdk_bs_get_io_unit_size(bs)); 1007 1008 spdk_json_write_named_uint64(w, "cluster_size", cluster_size); 1009 1010 spdk_json_write_object_end(w); 1011 } 1012 1013 static void 1014 rpc_bdev_lvol_get_lvstores(struct spdk_jsonrpc_request *request, 1015 const struct spdk_json_val *params) 1016 { 1017 struct rpc_bdev_lvol_get_lvstores req = {}; 1018 struct spdk_json_write_ctx *w; 1019 struct lvol_store_bdev *lvs_bdev = NULL; 1020 struct spdk_lvol_store *lvs = NULL; 1021 int rc; 1022 1023 if (params != NULL) { 1024 if (spdk_json_decode_object(params, rpc_bdev_lvol_get_lvstores_decoders, 1025 SPDK_COUNTOF(rpc_bdev_lvol_get_lvstores_decoders), 1026 &req)) { 1027 SPDK_INFOLOG(lvol_rpc, "spdk_json_decode_object failed\n"); 1028 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 1029 "spdk_json_decode_object failed"); 1030 goto cleanup; 1031 } 1032 1033 rc = vbdev_get_lvol_store_by_uuid_xor_name(req.uuid, req.lvs_name, &lvs); 1034 if (rc != 0) { 1035 spdk_jsonrpc_send_error_response(request, rc, spdk_strerror(-rc)); 1036 goto cleanup; 1037 } 1038 1039 lvs_bdev = vbdev_get_lvs_bdev_by_lvs(lvs); 1040 if (lvs_bdev == NULL) { 1041 spdk_jsonrpc_send_error_response(request, ENODEV, spdk_strerror(-ENODEV)); 1042 goto cleanup; 1043 } 1044 } 1045 1046 w = spdk_jsonrpc_begin_result(request); 1047 spdk_json_write_array_begin(w); 1048 1049 if (lvs_bdev != NULL) { 1050 rpc_dump_lvol_store_info(w, lvs_bdev); 1051 } else { 1052 for (lvs_bdev = vbdev_lvol_store_first(); lvs_bdev != NULL; 1053 lvs_bdev = vbdev_lvol_store_next(lvs_bdev)) { 1054 rpc_dump_lvol_store_info(w, lvs_bdev); 1055 } 1056 } 1057 spdk_json_write_array_end(w); 1058 1059 spdk_jsonrpc_end_result(request, w); 1060 1061 cleanup: 1062 free_rpc_bdev_lvol_get_lvstores(&req); 1063 } 1064 1065 SPDK_RPC_REGISTER("bdev_lvol_get_lvstores", rpc_bdev_lvol_get_lvstores, SPDK_RPC_RUNTIME) 1066 SPDK_RPC_REGISTER_ALIAS_DEPRECATED(bdev_lvol_get_lvstores, get_lvol_stores) 1067 1068 struct rpc_bdev_lvol_grow_lvstore { 1069 char *uuid; 1070 char *lvs_name; 1071 }; 1072 1073 static void 1074 free_rpc_bdev_lvol_grow_lvstore(struct rpc_bdev_lvol_grow_lvstore *req) 1075 { 1076 free(req->uuid); 1077 free(req->lvs_name); 1078 } 1079 1080 static const struct spdk_json_object_decoder rpc_bdev_lvol_grow_lvstore_decoders[] = { 1081 {"uuid", offsetof(struct rpc_bdev_lvol_grow_lvstore, uuid), spdk_json_decode_string, true}, 1082 {"lvs_name", offsetof(struct rpc_bdev_lvol_grow_lvstore, lvs_name), spdk_json_decode_string, true}, 1083 }; 1084 1085 static void 1086 rpc_bdev_lvol_grow_lvstore_cb(void *cb_arg, int lvserrno) 1087 { 1088 struct spdk_jsonrpc_request *request = cb_arg; 1089 1090 if (lvserrno != 0) { 1091 goto invalid; 1092 } 1093 1094 spdk_jsonrpc_send_bool_response(request, true); 1095 return; 1096 1097 invalid: 1098 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 1099 spdk_strerror(-lvserrno)); 1100 } 1101 1102 static void 1103 rpc_bdev_lvol_grow_lvstore(struct spdk_jsonrpc_request *request, 1104 const struct spdk_json_val *params) 1105 { 1106 struct rpc_bdev_lvol_grow_lvstore req = {}; 1107 struct spdk_lvol_store *lvs = NULL; 1108 int rc; 1109 1110 if (spdk_json_decode_object(params, rpc_bdev_lvol_grow_lvstore_decoders, 1111 SPDK_COUNTOF(rpc_bdev_lvol_grow_lvstore_decoders), 1112 &req)) { 1113 SPDK_INFOLOG(lvol_rpc, "spdk_json_decode_object failed\n"); 1114 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 1115 "spdk_json_decode_object failed"); 1116 goto cleanup; 1117 } 1118 1119 rc = vbdev_get_lvol_store_by_uuid_xor_name(req.uuid, req.lvs_name, &lvs); 1120 if (rc != 0) { 1121 spdk_jsonrpc_send_error_response(request, rc, spdk_strerror(-rc)); 1122 goto cleanup; 1123 } 1124 vbdev_lvs_grow(lvs, rpc_bdev_lvol_grow_lvstore_cb, request); 1125 1126 cleanup: 1127 free_rpc_bdev_lvol_grow_lvstore(&req); 1128 } 1129 SPDK_RPC_REGISTER("bdev_lvol_grow_lvstore", rpc_bdev_lvol_grow_lvstore, SPDK_RPC_RUNTIME) 1130