diff --git a/lib/vhost/vhost_rpc.c b/lib/vhost/vhost_rpc.c index 38a9be339..5d6743fe5 100644 --- a/lib/vhost/vhost_rpc.c +++ b/lib/vhost/vhost_rpc.c @@ -37,6 +37,7 @@ #include "spdk/rpc.h" #include "spdk/util.h" #include "spdk/string.h" +#include "spdk/env.h" #include "spdk/scsi.h" #include "spdk/vhost.h" @@ -102,60 +103,84 @@ SPDK_RPC_REGISTER("construct_vhost_scsi_controller", spdk_rpc_construct_vhost_sc struct rpc_remove_vhost_scsi_ctrlr { char *ctrlr; + + struct spdk_jsonrpc_request *request; }; static void free_rpc_remove_vhost_scsi_ctrlr(struct rpc_remove_vhost_scsi_ctrlr *req) { free(req->ctrlr); + free(req); } static const struct spdk_json_object_decoder rpc_remove_vhost_ctrlr[] = { {"ctrlr", offsetof(struct rpc_remove_vhost_scsi_ctrlr, ctrlr), spdk_json_decode_string }, }; -static void -spdk_rpc_remove_vhost_scsi_controller(struct spdk_jsonrpc_request *request, - const struct spdk_json_val *params) +static int +spdk_rpc_remove_vhost_scsi_controller_cb(struct spdk_vhost_dev *vdev, void *arg) { - struct rpc_remove_vhost_scsi_ctrlr req = {NULL}; + struct rpc_remove_vhost_scsi_ctrlr *ctx = arg; + struct spdk_jsonrpc_request *request = ctx->request; struct spdk_json_write_ctx *w; - struct spdk_vhost_dev *vdev; int rc; char buf[64]; - if (spdk_json_decode_object(params, rpc_remove_vhost_ctrlr, - SPDK_COUNTOF(rpc_remove_vhost_ctrlr), - &req)) { - SPDK_DEBUGLOG(SPDK_TRACE_VHOST_RPC, "spdk_json_decode_object failed\n"); - rc = -EINVAL; - goto invalid; - } - - if (!(vdev = spdk_vhost_dev_find(req.ctrlr))) { - rc = -ENODEV; - goto invalid; - } - rc = spdk_vhost_scsi_dev_remove(vdev); if (rc < 0) { goto invalid; } - free_rpc_remove_vhost_scsi_ctrlr(&req); + free_rpc_remove_vhost_scsi_ctrlr(ctx); w = spdk_jsonrpc_begin_result(request); if (w == NULL) { - return; + return 0; } spdk_json_write_bool(w, true); spdk_jsonrpc_end_result(request, w); + return 0; + +invalid: + free_rpc_remove_vhost_scsi_ctrlr(ctx); + spdk_strerror_r(-rc, buf, sizeof(buf)); + spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, buf); + return -1; +} + +static void +spdk_rpc_remove_vhost_scsi_controller(struct spdk_jsonrpc_request *request, + const struct spdk_json_val *params) +{ + struct rpc_remove_vhost_scsi_ctrlr *req; + char buf[64]; + int rc; + + req = calloc(1, sizeof(*req)); + if (req == NULL) { + rc = -ENOMEM; + goto invalid; + } + + req->request = request; + if (spdk_json_decode_object(params, rpc_remove_vhost_ctrlr, + SPDK_COUNTOF(rpc_remove_vhost_ctrlr), + req)) { + SPDK_DEBUGLOG(SPDK_TRACE_VHOST_RPC, "spdk_json_decode_object failed\n"); + rc = -EINVAL; + goto invalid; + } + + spdk_vhost_call_external_event(req->ctrlr, spdk_rpc_remove_vhost_scsi_controller_cb, req); return; invalid: + if (req) { + free_rpc_remove_vhost_scsi_ctrlr(req); + } spdk_strerror_r(-rc, buf, sizeof(buf)); - free_rpc_remove_vhost_scsi_ctrlr(&req); spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, buf); } SPDK_RPC_REGISTER("remove_vhost_scsi_controller", spdk_rpc_remove_vhost_scsi_controller) @@ -165,6 +190,8 @@ struct rpc_add_vhost_scsi_ctrlr_lun { char *ctrlr; uint32_t scsi_dev_num; char *lun_name; + + struct spdk_jsonrpc_request *request; }; static void @@ -172,6 +199,7 @@ free_rpc_add_vhost_scsi_ctrlr_lun(struct rpc_add_vhost_scsi_ctrlr_lun *req) { free(req->ctrlr); free(req->lun_name); + free(req); } static const struct spdk_json_object_decoder rpc_vhost_add_lun[] = { @@ -180,50 +208,81 @@ static const struct spdk_json_object_decoder rpc_vhost_add_lun[] = { {"lun_name", offsetof(struct rpc_add_vhost_scsi_ctrlr_lun, lun_name), spdk_json_decode_string }, }; +static int +spdk_rpc_add_vhost_scsi_lun_cb(struct spdk_vhost_dev *vdev, void *arg) +{ + struct rpc_add_vhost_scsi_ctrlr_lun *rpc = arg; + struct spdk_jsonrpc_request *request = rpc->request; + struct spdk_json_write_ctx *w; + int rc; + char buf[64]; + + if (vdev == NULL) { + rc = -ENODEV; + goto invalid; + } + + rc = spdk_vhost_scsi_dev_add_dev(vdev, rpc->scsi_dev_num, rpc->lun_name); + if (rc < 0) { + goto invalid; + } + + free_rpc_add_vhost_scsi_ctrlr_lun(rpc); + + w = spdk_jsonrpc_begin_result(request); + if (w == NULL) { + return -1; + } + + spdk_json_write_bool(w, true); + spdk_jsonrpc_end_result(request, w); + return 0; + +invalid: + free_rpc_add_vhost_scsi_ctrlr_lun(rpc); + spdk_strerror_r(-rc, buf, sizeof(buf)); + spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, buf); + return rc; +} + static void spdk_rpc_add_vhost_scsi_lun(struct spdk_jsonrpc_request *request, const struct spdk_json_val *params) { - struct rpc_add_vhost_scsi_ctrlr_lun req = {0}; - struct spdk_json_write_ctx *w; - struct spdk_vhost_dev *vdev; - int rc; + struct rpc_add_vhost_scsi_ctrlr_lun *req; char buf[64]; + int rc; + req = calloc(1, sizeof(*req)); + if (req == NULL) { + rc = -ENOMEM; + goto invalid; + } + + req->request = request; if (spdk_json_decode_object(params, rpc_vhost_add_lun, SPDK_COUNTOF(rpc_vhost_add_lun), - &req)) { + req)) { SPDK_DEBUGLOG(SPDK_TRACE_VHOST_RPC, "spdk_json_decode_object failed\n"); rc = -EINVAL; goto invalid; } - vdev = spdk_vhost_dev_find(req.ctrlr); - if (vdev == NULL) { - SPDK_ERRLOG("Controller %s is not defined.\n", req.ctrlr); - rc = -ENODEV; + if (req->ctrlr == NULL) { + SPDK_ERRLOG("No controller name\n"); + rc = -EINVAL; goto invalid; } - rc = spdk_vhost_scsi_dev_add_dev(vdev, req.scsi_dev_num, req.lun_name); - if (rc < 0) { - goto invalid; - } + spdk_vhost_call_external_event(req->ctrlr, spdk_rpc_add_vhost_scsi_lun_cb, req); - free_rpc_add_vhost_scsi_ctrlr_lun(&req); - - w = spdk_jsonrpc_begin_result(request); - if (w == NULL) { - return; - } - - spdk_json_write_bool(w, true); - spdk_jsonrpc_end_result(request, w); return; invalid: + if (req) { + free_rpc_add_vhost_scsi_ctrlr_lun(req); + } spdk_strerror_r(-rc, buf, sizeof(buf)); - free_rpc_add_vhost_scsi_ctrlr_lun(&req); spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, buf); } SPDK_RPC_REGISTER("add_vhost_scsi_lun", spdk_rpc_add_vhost_scsi_lun) @@ -231,12 +290,15 @@ SPDK_RPC_REGISTER("add_vhost_scsi_lun", spdk_rpc_add_vhost_scsi_lun) struct rpc_remove_vhost_scsi_ctrlr_dev { char *ctrlr; uint32_t scsi_dev_num; + + struct spdk_jsonrpc_request *request; }; static void free_rpc_remove_vhost_scsi_ctrlr_dev(struct rpc_remove_vhost_scsi_ctrlr_dev *req) { free(req->ctrlr); + free(req); } static const struct spdk_json_object_decoder rpc_vhost_remove_dev[] = { @@ -244,50 +306,78 @@ static const struct spdk_json_object_decoder rpc_vhost_remove_dev[] = { {"scsi_dev_num", offsetof(struct rpc_remove_vhost_scsi_ctrlr_dev, scsi_dev_num), spdk_json_decode_uint32}, }; +static int +spdk_rpc_remove_vhost_scsi_dev_cb(struct spdk_vhost_dev *vdev, void *arg) +{ + struct rpc_remove_vhost_scsi_ctrlr_dev *rpc = arg; + struct spdk_jsonrpc_request *request = rpc->request; + struct spdk_json_write_ctx *w; + int rc; + char buf[64]; + + if (vdev == NULL) { + rc = -ENODEV; + goto invalid; + } + + rc = spdk_vhost_scsi_dev_remove_dev(vdev, rpc->scsi_dev_num); + if (rc < 0) { + goto invalid; + } + + free_rpc_remove_vhost_scsi_ctrlr_dev(rpc); + + w = spdk_jsonrpc_begin_result(request); + if (w == NULL) { + return -1; + } + + spdk_json_write_bool(w, true); + spdk_jsonrpc_end_result(request, w); + return 0; + +invalid: + free_rpc_remove_vhost_scsi_ctrlr_dev(rpc); + spdk_strerror_r(-rc, buf, sizeof(buf)); + spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, buf); + return rc; +} + static void spdk_rpc_remove_vhost_scsi_dev(struct spdk_jsonrpc_request *request, const struct spdk_json_val *params) { - struct rpc_remove_vhost_scsi_ctrlr_dev req = {0}; - struct spdk_json_write_ctx *w; - struct spdk_vhost_dev *vdev; + struct rpc_remove_vhost_scsi_ctrlr_dev *req; int rc; char buf[64]; + req = calloc(1, sizeof(*req)); + if (req == NULL) { + rc = -ENOMEM; + goto invalid; + } + + req->request = request; if (spdk_json_decode_object(params, rpc_vhost_remove_dev, SPDK_COUNTOF(rpc_vhost_remove_dev), - &req)) { + req)) { SPDK_DEBUGLOG(SPDK_TRACE_VHOST_RPC, "spdk_json_decode_object failed\n"); rc = -EINVAL; goto invalid; } - if (!(vdev = spdk_vhost_dev_find(req.ctrlr))) { - rc = -ENODEV; - goto invalid; - } + spdk_vhost_call_external_event(req->ctrlr, spdk_rpc_remove_vhost_scsi_dev_cb, req); - rc = spdk_vhost_scsi_dev_remove_dev(vdev, req.scsi_dev_num); - if (rc < 0) { - goto invalid; - } - - free_rpc_remove_vhost_scsi_ctrlr_dev(&req); - - w = spdk_jsonrpc_begin_result(request); - if (w == NULL) { - return; - } - - spdk_json_write_bool(w, true); - spdk_jsonrpc_end_result(request, w); return; invalid: + if (req) { + free_rpc_remove_vhost_scsi_ctrlr_dev(req); + } spdk_strerror_r(-rc, buf, sizeof(buf)); - free_rpc_remove_vhost_scsi_ctrlr_dev(&req); spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, buf); } + SPDK_RPC_REGISTER("remove_vhost_scsi_dev", spdk_rpc_remove_vhost_scsi_dev) struct rpc_vhost_blk_ctrlr { @@ -356,6 +446,8 @@ SPDK_RPC_REGISTER("construct_vhost_blk_controller", spdk_rpc_construct_vhost_blk struct rpc_remove_vhost_blk_ctrlr { char *ctrlr; + + struct spdk_jsonrpc_request *request; }; static const struct spdk_json_object_decoder rpc_remove_vhost_blk_ctrlr[] = { @@ -366,49 +458,72 @@ static void free_rpc_remove_vhost_blk_ctrlr(struct rpc_remove_vhost_blk_ctrlr *req) { free(req->ctrlr); + free(req); } -static void -spdk_rpc_remove_vhost_blk_controller(struct spdk_jsonrpc_request *request, - const struct spdk_json_val *params) +static int +spdk_rpc_remove_vhost_blk_controller_cb(struct spdk_vhost_dev *vdev, void *arg) { - struct rpc_remove_vhost_blk_ctrlr req = {NULL}; + struct rpc_remove_vhost_blk_ctrlr *ctx = arg; + struct spdk_jsonrpc_request *request = ctx->request; struct spdk_json_write_ctx *w; - struct spdk_vhost_dev *vdev; int rc; char buf[64]; - if (spdk_json_decode_object(params, rpc_remove_vhost_blk_ctrlr, - SPDK_COUNTOF(rpc_remove_vhost_blk_ctrlr), &req)) { - SPDK_DEBUGLOG(SPDK_TRACE_VHOST_RPC, "spdk_json_decode_object failed\n"); - rc = -EINVAL; - goto invalid; - } - - if (!(vdev = spdk_vhost_dev_find(req.ctrlr))) { - rc = -ENODEV; - goto invalid; - } - rc = spdk_vhost_blk_destroy(vdev); if (rc < 0) { goto invalid; } - free_rpc_remove_vhost_blk_ctrlr(&req); + free_rpc_remove_vhost_blk_ctrlr(ctx); w = spdk_jsonrpc_begin_result(request); if (w == NULL) { - return; + return 0; } spdk_json_write_bool(w, true); spdk_jsonrpc_end_result(request, w); + return 0; + +invalid: + free_rpc_remove_vhost_blk_ctrlr(ctx); + spdk_strerror_r(-rc, buf, sizeof(buf)); + spdk_jsonrpc_send_error_response(request, + SPDK_JSONRPC_ERROR_INVALID_PARAMS, buf); + return -1; +} + +static void +spdk_rpc_remove_vhost_blk_controller(struct spdk_jsonrpc_request *request, + const struct spdk_json_val *params) +{ + struct rpc_remove_vhost_blk_ctrlr *req; + char buf[64]; + int rc; + + req = calloc(1, sizeof(*req)); + if (req == NULL) { + rc = -ENOMEM; + goto invalid; + } + + req->request = request; + if (spdk_json_decode_object(params, rpc_remove_vhost_blk_ctrlr, + SPDK_COUNTOF(rpc_remove_vhost_blk_ctrlr), req)) { + SPDK_DEBUGLOG(SPDK_TRACE_VHOST_RPC, "spdk_json_decode_object failed\n"); + rc = -EINVAL; + goto invalid; + } + + spdk_vhost_call_external_event(req->ctrlr, spdk_rpc_remove_vhost_blk_controller_cb, req); return; invalid: + if (req) { + free_rpc_remove_vhost_blk_ctrlr(req); + } spdk_strerror_r(-rc, buf, sizeof(buf)); - free_rpc_remove_vhost_blk_ctrlr(&req); spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, buf);