Commit 3fa22056 authored by Michael Haeuptle's avatar Michael Haeuptle Committed by Tomasz Zawadzki
Browse files

lib/nvmf: custom admin cmd handler



    This commit provides the capability to install a
    custom admin command handler for NVMF.
    It can be used to implement or replace NVMe admin commands that
    are currently not handled by the NVMF subsystem.

    The handler implementation is pretty generic and the handler function
    has to figure out what to do with the command based on the bdevs
    that are configured for the subsystem.
    In cases where admin commands need to be forwarded to an NVMe bdev,
    the commit provides functions that allow access to the underlying bdev.

    There is an example handler in lib/nvmf/custom_cmd_hdlr.c.

Change-Id: I4f9d538c53669c176a836e8bdd379db0070a87dc
Signed-off-by: default avatarMichael Haeuptle <michael.haeuptle@hpe.com>
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/479167


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarShuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatar <jacek.kalwas@intel.com>
parent d0cbb468
Loading
Loading
Loading
Loading
+19 −0
Original line number Diff line number Diff line
@@ -18,6 +18,25 @@ parameter.

`spdk_ftl_punit_range` and `ftl_module_init_opts` structures were removed.

### nvmf

Support for custom NVMe admin command handlers and admin command passthru
in the NVMF subsystem.

It is now possible to set a custom handler for a specific NVMe admin command.
For example, vendor specific admin commands can now be intercepted by implementing
a function handling the command.
Further NVMe admin commands can be forwarded straight to an underlying NVMe bdev.

The functions `spdk_nvmf_set_custom_admin_cmd_hdlr` and `spdk_nvmf_set_passthru_admin_cmd`
in `spdk_internal/nvmf.h` expose this functionality. There is an example custom admin handler
for the NVMe IDENTIFY CTRLR in `lib/nvmf/custom_cmd_hdlr.c`. This handler gets the SN, MN, FR, IEEE, FGUID
attributes from the first NVMe drive in the NVMF subsystem and returns it to the NVMF initiator (sn and mn attributes
specified during NVMF subsystem creation RPC will be overwritten).

This handler is enabled by default and can be disabled by adding
`spdk_nvmf_set_custom_admin_cmd_hdlr(SPDK_NVME_OPC_IDENTIFY, NULL);` to a target application.

### sock

Added spdk_sock_writev_async for performing asynchronous writes to sockets. This call will
+2 −0
Original line number Diff line number Diff line
@@ -1221,6 +1221,8 @@ enum spdk_nvme_path_status_code {
	SPDK_NVME_SC_ABORTED_BY_HOST			= 0x71,
};

#define SPDK_NVME_MAX_OPC 0xff

/**
 * Admin opcodes
 */
+9 −0
Original line number Diff line number Diff line
@@ -974,6 +974,15 @@ const char *spdk_nvmf_subsystem_get_nqn(struct spdk_nvmf_subsystem *subsystem);
 */
enum spdk_nvmf_subtype spdk_nvmf_subsystem_get_type(struct spdk_nvmf_subsystem *subsystem);

/**
 * Get maximum namespace id of the specified subsystem.
 *
 * \param subsystem Subsystem to query.
 *
 * \return maximum namespace id
 */
uint32_t spdk_nvmf_subsystem_get_max_nsid(struct spdk_nvmf_subsystem *subsystem);

/**
 * Initialize transport options
 *
+25 −3
Original line number Diff line number Diff line
@@ -31,11 +31,12 @@
 *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef SPDK_NVMF_INTERNAL_H_
#define SPDK_NVMF_INTERNAL_H_
#ifndef SPDK_INTERNAL_NVMF_H_
#define SPDK_INTERNAL_NVMF_H_

#include "spdk/stdinc.h"
#include "spdk/nvmf.h"
#include "spdk/bdev.h"

typedef enum _spdk_nvmf_request_exec_status {
	SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE,
@@ -50,4 +51,25 @@ int spdk_nvmf_ctrlr_identify_ns(struct spdk_nvmf_ctrlr *ctrlr,
				struct spdk_nvme_cpl *rsp,
				struct spdk_nvme_ns_data *nsdata);

#endif /* SPDK_NVMF_INTERNAL_H_ */
typedef int (*spdk_nvmf_custom_cmd_hdlr)(struct spdk_nvmf_request *req);
void spdk_nvmf_set_custom_admin_cmd_hdlr(uint8_t opc, spdk_nvmf_custom_cmd_hdlr hdlr);

void spdk_nvmf_set_passthru_admin_cmd(uint8_t opc, uint32_t forward_nsid);

typedef void (*spdk_nvmf_nvme_passthru_cmd_cb)(struct spdk_nvmf_request *req);
int spdk_nvmf_bdev_ctrlr_nvme_passthru_admin(struct spdk_bdev *bdev, struct spdk_bdev_desc *desc,
		struct spdk_io_channel *ch, struct spdk_nvmf_request *req, spdk_nvmf_nvme_passthru_cmd_cb cb_fn);

int spdk_nvmf_request_get_bdev(uint32_t nsid,
			       struct spdk_nvmf_request *req,
			       struct spdk_bdev **bdev,
			       struct spdk_bdev_desc **desc,
			       struct spdk_io_channel **ch);
struct spdk_nvmf_ctrlr *spdk_nvmf_request_get_ctrlr(struct spdk_nvmf_request *req);
struct spdk_nvmf_subsystem *spdk_nvmf_request_get_subsystem(struct spdk_nvmf_request *req);
void spdk_nvmf_request_get_data(struct spdk_nvmf_request *req, void **data, uint32_t *length);
struct spdk_nvme_cmd *spdk_nvmf_request_get_cmd(struct spdk_nvmf_request *req);
struct spdk_nvme_cpl *spdk_nvmf_request_get_response(struct spdk_nvmf_request *req);
int spdk_nvmf_custom_identify_hdlr(struct spdk_nvmf_request *req);

#endif /* SPDK_INTERNAL_NVMF_H_ */
+2 −1
Original line number Diff line number Diff line
@@ -35,7 +35,8 @@ SPDK_ROOT_DIR := $(abspath $(CURDIR)/../..)
include $(SPDK_ROOT_DIR)/mk/spdk.common.mk

C_SRCS = ctrlr.c ctrlr_discovery.c ctrlr_bdev.c \
	 subsystem.c nvmf.c nvmf_rpc.c transport.c tcp.c
	 subsystem.c nvmf.c nvmf_rpc.c transport.c tcp.c \
	 custom_cmd_hdlr.c

C_SRCS-$(CONFIG_RDMA) += rdma.c
LIBNAME = nvmf
Loading