Commit 153f03cf authored by Jonathan Teh's avatar Jonathan Teh Committed by Tomasz Zawadzki
Browse files

bdev/nvme: Add bdev_nvme_reset_controller rpc



Implement bdev_nvme_reset_controller rpc, which allows the NVMe
controller to be reset over RPC. Implement bdev_nvme_reset_rpc()
which starts the reset of the controller and returns the result of
the controller reset via the callback function after it completes.

Signed-off-by: default avatarJonathan Teh <jonathan.teh@mayadata.io>
Change-Id: Id98d5e56feb315b7e44e9bb5e5f495e9b1cd1de0
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/8456


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: Broadcom CI <spdk-ci.pdl@broadcom.com>
Community-CI: Mellanox Build Bot
Reviewed-by: default avatarShuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: default avatarTomasz Zawadzki <tomasz.zawadzki@intel.com>
parent 3c6b670d
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -92,6 +92,8 @@ The default value is `false`.
New APIs, `spdk_nvme_ctrlr_reset_async` and `spdk_nvme_ctrlr_reset_poll_async`, have been added to
reset a controller asynchronously.

New RPC `bdev_nvme_reset_controller` was added, to reset an NVMe controller.

### rpc

New RPC `bdev_rbd_register_cluster` and `bdev_rbd_unregister_cluster` was added, it allows to create
+37 −0
Original line number Diff line number Diff line
@@ -3006,6 +3006,43 @@ Example response:
}
~~~

## bdev_nvme_reset_controller {#rpc_bdev_nvme_reset_controller}

Reset NVMe controller.

Returns true if the controller reset was successful, false otherwise.

### Parameters

Name                    | Optional | Type        | Description
----------------------- | -------- | ----------- | -----------
name                    | Required | string      | NVMe controller name

### Example

Example request:

~~~
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "bdev_nvme_reset_controller",
  "params": {
    "name": "Nvme0"
  }
}
~~~

Example response:

~~~
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": true
}
~~~

## bdev_nvme_cuse_register {#rpc_bdev_nvme_cuse_register}

Register CUSE device on NVMe controller.
+13 −0
Original line number Diff line number Diff line
@@ -660,6 +660,19 @@ bdev_nvme_reset(struct nvme_ctrlr *nvme_ctrlr)
	return 0;
}

int
bdev_nvme_reset_rpc(struct nvme_ctrlr *nvme_ctrlr, bdev_nvme_reset_cb cb_fn, void *cb_arg)
{
	int rc;

	rc = bdev_nvme_reset(nvme_ctrlr);
	if (rc == 0) {
		nvme_ctrlr->reset_cb_fn = cb_fn;
		nvme_ctrlr->reset_cb_arg = cb_arg;
	}
	return rc;
}

static void
bdev_nvme_reset_io_complete(void *cb_arg, int rc)
{
+12 −0
Original line number Diff line number Diff line
@@ -92,4 +92,16 @@ struct spdk_nvme_ctrlr *bdev_nvme_get_ctrlr(struct spdk_bdev *bdev);
 */
int bdev_nvme_delete(const char *name, const struct spdk_nvme_transport_id *trid);

/**
 * Reset NVMe controller.
 *
 * \param nvme_ctrlr The specified NVMe controller to reset
 * \param cb_fn Function to be called back after reset completes
 * \param cb_arg Argument for callback function
 * \return zero on success. Negated errno on the following error conditions:
 * -EBUSY: controller is being destroyed.
 * -EAGAIN: controller is already being reset.
 */
int bdev_nvme_reset_rpc(struct nvme_ctrlr *nvme_ctrlr, bdev_nvme_reset_cb cb_fn, void *cb_arg);

#endif /* SPDK_BDEV_NVME_H */
+56 −0
Original line number Diff line number Diff line
@@ -1089,3 +1089,59 @@ rpc_bdev_nvme_get_transport_statistics(struct spdk_jsonrpc_request *request,
}
SPDK_RPC_REGISTER("bdev_nvme_get_transport_statistics", rpc_bdev_nvme_get_transport_statistics,
		  SPDK_RPC_RUNTIME)

struct rpc_bdev_nvme_reset_controller_req {
	char *name;
};

static void
free_rpc_bdev_nvme_reset_controller_req(struct rpc_bdev_nvme_reset_controller_req *r)
{
	free(r->name);
}

static const struct spdk_json_object_decoder rpc_bdev_nvme_reset_controller_req_decoders[] = {
	{"name", offsetof(struct rpc_bdev_nvme_reset_controller_req, name), spdk_json_decode_string},
};

static void
_rpc_bdev_nvme_reset_controller_cb(void *cb_arg, int rc)
{
	struct spdk_jsonrpc_request *request = cb_arg;

	spdk_jsonrpc_send_bool_response(request, rc == 0);
}

static void
rpc_bdev_nvme_reset_controller(struct spdk_jsonrpc_request *request,
			       const struct spdk_json_val *params)
{
	struct rpc_bdev_nvme_reset_controller_req req = {NULL};
	struct nvme_ctrlr *nvme_ctrlr;
	int rc;

	if (spdk_json_decode_object(params, rpc_bdev_nvme_reset_controller_req_decoders,
				    SPDK_COUNTOF(rpc_bdev_nvme_reset_controller_req_decoders),
				    &req)) {
		SPDK_ERRLOG("spdk_json_decode_object failed\n");
		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, spdk_strerror(EINVAL));
		goto cleanup;
	}

	nvme_ctrlr = nvme_ctrlr_get_by_name(req.name);
	if (nvme_ctrlr == NULL) {
		SPDK_ERRLOG("Failed at device lookup\n");
		spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV));
		goto cleanup;
	}

	rc = bdev_nvme_reset_rpc(nvme_ctrlr, _rpc_bdev_nvme_reset_controller_cb, request);
	if (rc != 0) {
		SPDK_NOTICELOG("Failed at bdev_nvme_reset_rpc\n");
		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, spdk_strerror(-rc));
	}

cleanup:
	free_rpc_bdev_nvme_reset_controller_req(&req);
}
SPDK_RPC_REGISTER("bdev_nvme_reset_controller", rpc_bdev_nvme_reset_controller, SPDK_RPC_RUNTIME)
Loading