Commit d9a11fd5 authored by Tomasz Zawadzki's avatar Tomasz Zawadzki Committed by Jim Harris
Browse files

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: default avatarTomasz 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: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
parent 15a50180
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -3044,8 +3044,9 @@ int spdk_nvme_cuse_register(struct spdk_nvme_ctrlr *ctrlr);
 *
 * \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,
		       uint32_t len, size_t mps,
+12 −2
Original line number Diff line number Diff line
@@ -942,12 +942,22 @@ spdk_nvme_cuse_register(struct spdk_nvme_ctrlr *ctrlr)
	return rc;
}

void
int
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);

	return 0;
}

char *
+6 −1
Original line number Diff line number Diff line
@@ -118,6 +118,7 @@ spdk_rpc_nvme_cuse_unregister(struct spdk_jsonrpc_request *request,
	struct rpc_nvme_cuse_unregister req = {};
	struct spdk_json_write_ctx *w;
	struct nvme_bdev_ctrlr *bdev_ctrlr = NULL;
	int rc;

	if (spdk_json_decode_object(params, 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;
	}

	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);
	spdk_json_write_bool(w, true);
+3 −0
Original line number Diff line number Diff line
@@ -36,6 +36,9 @@ if [ -c "$ctrlr" ]; then
	exit 1
fi

# Verify removing non-existent cuse device
$rpc_py bdev_nvme_cuse_unregister -n Nvme0 && false

$rpc_py bdev_nvme_cuse_register -n Nvme0
sleep 1