cuse: fix nvme_cuse unregister segfault
Unregistering nvme_cuse when the device did not exist resulted in SEGFAULT within nvme_io_msg_ctrlr_unregister(). To prevent that, when no nvme_cuse is registered for the ctrlr do not unregister nvme_io_msg_producer. RPC and spdk_nvme_cuse_unregister() now return an error. Signed-off-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com> Change-Id: Id77cebe23ff91023a24cfe091f5f62a76a9175fd Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/1921 Community-CI: Mellanox Build Bot Community-CI: Broadcom CI Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Ben Walker <benjamin.walker@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com>
This commit is contained in:
parent
15a5018067
commit
d9a11fd5b1
@ -3044,8 +3044,9 @@ int spdk_nvme_cuse_register(struct spdk_nvme_ctrlr *ctrlr);
|
|||||||
*
|
*
|
||||||
* \param ctrlr Opaque handle to the NVMe controller.
|
* \param ctrlr Opaque handle to the NVMe controller.
|
||||||
*
|
*
|
||||||
|
* \return 0 on success. Negated errno on failure.
|
||||||
*/
|
*/
|
||||||
void spdk_nvme_cuse_unregister(struct spdk_nvme_ctrlr *ctrlr);
|
int spdk_nvme_cuse_unregister(struct spdk_nvme_ctrlr *ctrlr);
|
||||||
|
|
||||||
int spdk_nvme_map_prps(void *prv, struct spdk_nvme_cmd *cmd, struct iovec *iovs,
|
int spdk_nvme_map_prps(void *prv, struct spdk_nvme_cmd *cmd, struct iovec *iovs,
|
||||||
uint32_t len, size_t mps,
|
uint32_t len, size_t mps,
|
||||||
|
@ -942,12 +942,22 @@ spdk_nvme_cuse_register(struct spdk_nvme_ctrlr *ctrlr)
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
int
|
||||||
spdk_nvme_cuse_unregister(struct spdk_nvme_ctrlr *ctrlr)
|
spdk_nvme_cuse_unregister(struct spdk_nvme_ctrlr *ctrlr)
|
||||||
{
|
{
|
||||||
nvme_cuse_stop(ctrlr);
|
struct cuse_device *ctrlr_device;
|
||||||
|
|
||||||
|
ctrlr_device = nvme_cuse_get_cuse_ctrlr_device(ctrlr);
|
||||||
|
if (!ctrlr_device) {
|
||||||
|
SPDK_ERRLOG("Cannot find associated CUSE device\n");
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
cuse_nvme_ctrlr_stop(ctrlr_device);
|
||||||
|
|
||||||
nvme_io_msg_ctrlr_unregister(ctrlr, &cuse_nvme_io_msg_producer);
|
nvme_io_msg_ctrlr_unregister(ctrlr, &cuse_nvme_io_msg_producer);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *
|
char *
|
||||||
|
@ -118,6 +118,7 @@ spdk_rpc_nvme_cuse_unregister(struct spdk_jsonrpc_request *request,
|
|||||||
struct rpc_nvme_cuse_unregister req = {};
|
struct rpc_nvme_cuse_unregister req = {};
|
||||||
struct spdk_json_write_ctx *w;
|
struct spdk_json_write_ctx *w;
|
||||||
struct nvme_bdev_ctrlr *bdev_ctrlr = NULL;
|
struct nvme_bdev_ctrlr *bdev_ctrlr = NULL;
|
||||||
|
int rc;
|
||||||
|
|
||||||
if (spdk_json_decode_object(params, rpc_nvme_cuse_unregister_decoders,
|
if (spdk_json_decode_object(params, rpc_nvme_cuse_unregister_decoders,
|
||||||
SPDK_COUNTOF(rpc_nvme_cuse_unregister_decoders),
|
SPDK_COUNTOF(rpc_nvme_cuse_unregister_decoders),
|
||||||
@ -135,7 +136,11 @@ spdk_rpc_nvme_cuse_unregister(struct spdk_jsonrpc_request *request,
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
spdk_nvme_cuse_unregister(bdev_ctrlr->ctrlr);
|
rc = spdk_nvme_cuse_unregister(bdev_ctrlr->ctrlr);
|
||||||
|
if (rc) {
|
||||||
|
spdk_jsonrpc_send_error_response(request, rc, spdk_strerror(-rc));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
w = spdk_jsonrpc_begin_result(request);
|
w = spdk_jsonrpc_begin_result(request);
|
||||||
spdk_json_write_bool(w, true);
|
spdk_json_write_bool(w, true);
|
||||||
|
@ -36,6 +36,9 @@ if [ -c "$ctrlr" ]; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Verify removing non-existent cuse device
|
||||||
|
$rpc_py bdev_nvme_cuse_unregister -n Nvme0 && false
|
||||||
|
|
||||||
$rpc_py bdev_nvme_cuse_register -n Nvme0
|
$rpc_py bdev_nvme_cuse_register -n Nvme0
|
||||||
sleep 1
|
sleep 1
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user