NVMe-oF Target: Add FC transport.
- New files and updates to existing SPDK files to add the NVMf-FC transport. - Depends on an existing low level driver library. This driver is not part of SPDK repository. - Makefile updates to build FC transport (using CONFIG_FC) - Update configure script for FC build. - New FC unit test for FC-LS commands. - Update unittest.sh to run FC unit test (when built). Signed-off-by: John Barnard <john.barnard@broadcom.com> Signed-off-by: Anil Veerabhadrappa <anil.veerabhadrappa@broadcom.com> Change-Id: If31d4d25feab76c2dbe90a7faf71d465c2c3a354 Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/450077 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com> Reviewed-by: Ben Walker <benjamin.walker@intel.com>
This commit is contained in:
parent
e10fc6ea00
commit
ed56a3d482
@ -22,6 +22,12 @@ and `spdk_dix_remap_ref_tag` have been added to remap DIF reference tag.
|
||||
New APIs `spdk_dif_update_crc32c` and `spdk_dif_update_crc32c_stream` have been
|
||||
added to compute CRC-32C checksum for extended LBA payload.
|
||||
|
||||
### NVME-oF Target (FC)
|
||||
|
||||
New Fibre Channel transport for NVMe over Fabrics target. Requires an FC HBA to use.
|
||||
Also, requires a Fibre Channel HBA low level driver (lld) library. The driver library
|
||||
and API header file path can be provided as an argument to "--with-fc".
|
||||
|
||||
### NVMe-oF Target
|
||||
|
||||
Persistent reservation emulation has been added to the NVMe-oF target. Persistent reservation
|
||||
|
5
CONFIG
5
CONFIG
@ -94,6 +94,11 @@ CONFIG_FIO_SOURCE_DIR=/usr/src/fio
|
||||
CONFIG_RDMA=n
|
||||
CONFIG_RDMA_SEND_WITH_INVAL=n
|
||||
|
||||
# Enable FC support for the NVMf target.
|
||||
# Requires FC low level driver (from FC vendor)
|
||||
CONFIG_FC=n
|
||||
CONFIG_FC_PATH=
|
||||
|
||||
# Build Ceph RBD support in bdev modules
|
||||
# Requires librbd development libraries
|
||||
CONFIG_RBD=n
|
||||
|
@ -48,4 +48,11 @@ ifeq ($(OS),Linux)
|
||||
SPDK_LIB_LIST += event_nbd nbd
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_FC),y)
|
||||
ifneq ($(strip $(CONFIG_FC_PATH)),)
|
||||
SYS_LIBS += -L$(CONFIG_FC_PATH)
|
||||
endif
|
||||
SYS_LIBS += -lufc
|
||||
endif
|
||||
|
||||
include $(SPDK_ROOT_DIR)/mk/spdk.app.mk
|
||||
|
@ -58,6 +58,13 @@ ifeq ($(OS),Linux)
|
||||
SPDK_LIB_LIST += event_nbd nbd
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_FC),y)
|
||||
ifneq ($(strip $(CONFIG_FC_PATH)),)
|
||||
SYS_LIBS += -L$(CONFIG_FC_PATH)
|
||||
endif
|
||||
SYS_LIBS += -lufc
|
||||
endif
|
||||
|
||||
include $(SPDK_ROOT_DIR)/mk/spdk.app.mk
|
||||
|
||||
install: $(APP)
|
||||
|
25
configure
vendored
25
configure
vendored
@ -69,6 +69,10 @@ function usage()
|
||||
echo " No path required."
|
||||
echo " rdma Build RDMA transport for NVMf target and initiator."
|
||||
echo " No path required."
|
||||
echo " fc Build FC transport for NVMf target."
|
||||
echo " If an argument is provided, it is considered a directory containing"
|
||||
echo " libufc.a and fc_lld.h. Otherwise the regular system paths will"
|
||||
echo " be searched."
|
||||
echo " shared Build spdk shared libraries."
|
||||
echo " No path required."
|
||||
echo " iscsi-initiator Build with iscsi bdev module."
|
||||
@ -218,6 +222,18 @@ for i in "$@"; do
|
||||
--without-rdma)
|
||||
CONFIG[RDMA]=n
|
||||
;;
|
||||
--with-fc=*)
|
||||
CONFIG[FC]=y
|
||||
CONFIG[FC_PATH]=$(readlink -f ${i#*=})
|
||||
;;
|
||||
--with-fc)
|
||||
CONFIG[FC]=y
|
||||
CONFIG[FC_PATH]=
|
||||
;;
|
||||
--without-fc)
|
||||
CONFIG[FC]=n
|
||||
CONFIG[FC_PATH]=
|
||||
;;
|
||||
--with-shared)
|
||||
CONFIG[SHARED]=y
|
||||
;;
|
||||
@ -499,6 +515,15 @@ than or equal to 4.14 will see significantly reduced performance.
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ "${CONFIG[FC]}" = "y" ]]; then
|
||||
if [[ -n "${CONFIG[FC_PATH]}" ]]; then
|
||||
if [ ! -d "${CONFIG[FC_PATH]}" ]; then
|
||||
echo "${CONFIG[FC_PATH]}: directory not found"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ "${CONFIG[ISAL]}" = "y" ]] || [[ "${CONFIG[CRYPTO]}" = "y" ]]; then
|
||||
ver=$(nasm -v | awk '{print $3}' | sed 's/[^0-9]*//g')
|
||||
if [[ "${ver:0:1}" -le "2" ]] && [[ "${ver:0:3}" -le "213" ]] && [[ "${ver:0:5}" -lt "21303" ]]; then
|
||||
|
25
doc/nvmf.md
25
doc/nvmf.md
@ -125,6 +125,31 @@ Using .ini style configuration files for configuration of the NVMe-oF target is
|
||||
be replaced with JSON based RPCs. .ini style configuration files can be converted to json format by way
|
||||
of the new script `scripts/config_converter.py`.
|
||||
|
||||
## FC transport support {#nvmf_fc_transport}
|
||||
|
||||
To build nvmf_tgt with the FC transport, there is an additional FC LLD (Low Level Driver) code dependency.
|
||||
Please contact your FC vendor for instructions to obtain FC driver module.
|
||||
|
||||
### Broadcom FC LLD code
|
||||
FC LLD driver for Broadcom FC NVMe capable adapters can be obtained from,
|
||||
https://github.com/ecdufcdrvr/bcmufctdrvr.
|
||||
|
||||
### Fetch FC LLD module and then build SPDK with FC enabled:
|
||||
After cloning SPDK repo and initialize submodules, FC LLD library is built which then can be linked with
|
||||
the fc transport.
|
||||
|
||||
~~~{.sh}
|
||||
git clone https://github.com/spdk/spdk spdk
|
||||
git clone https://github.com/ecdufcdrvr/bcmufctdrvr fc
|
||||
cd spdk
|
||||
git submodule update --init
|
||||
cd ../fc
|
||||
make DPDK_DIR=../spdk/dpdk/build SPDK_DIR=../spdk
|
||||
cd ../spdk
|
||||
./configure --with-fc=../fc/build
|
||||
make
|
||||
~~~
|
||||
|
||||
### Using RPCs {#nvmf_config_rpc}
|
||||
|
||||
Start the nvmf_tgt application with elevated privileges. Once the target is started,
|
||||
|
@ -146,6 +146,22 @@
|
||||
# Set whether to use the C2H Success optimization, only used for TCP transport.
|
||||
# C2HSuccess true
|
||||
|
||||
# Define FC transport
|
||||
#[Transport]
|
||||
# Set FC transport type.
|
||||
#Type FC
|
||||
|
||||
# Set the maximum number of submission and completion queues per session.
|
||||
# Setting this to '8', for example, allows for 8 submission and 8 completion queues
|
||||
# per session.
|
||||
#MaxQueuesPerSession 5
|
||||
|
||||
# Set the maximum number of outstanding I/O per queue.
|
||||
#MaxQueueDepth 128
|
||||
|
||||
# Set the maximum I/O size. Must be a multiple of 4096.
|
||||
#MaxIOSize 65536
|
||||
|
||||
[Nvme]
|
||||
# NVMe Device Whitelist
|
||||
# Users may specify which NVMe devices to claim by their transport id.
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright (c) 2018 Broadcom. All Rights Reserved.
|
||||
* Copyright (c) 2018-2019 Broadcom. All Rights Reserved.
|
||||
* The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -400,4 +400,14 @@ struct spdk_nvmf_fc_ls_rjt {
|
||||
};
|
||||
SPDK_STATIC_ASSERT(sizeof(struct spdk_nvmf_fc_ls_rjt) == 40, "size_mismatch");
|
||||
|
||||
/*
|
||||
* FC World Wide Name
|
||||
*/
|
||||
struct spdk_nvmf_fc_wwn {
|
||||
union {
|
||||
uint64_t wwn; /* World Wide Names consist of eight bytes */
|
||||
uint8_t octets[sizeof(uint64_t)];
|
||||
} u;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -59,4 +59,12 @@ endif
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_FC),y)
|
||||
C_SRCS += fc.c fc_ls.c
|
||||
CFLAGS += -I$(CURDIR)
|
||||
ifneq ($(strip $(CONFIG_FC_PATH)),)
|
||||
CFLAGS += -I$(CONFIG_FC_PATH)
|
||||
endif
|
||||
endif
|
||||
|
||||
include $(SPDK_ROOT_DIR)/mk/spdk.lib.mk
|
||||
|
3986
lib/nvmf/fc.c
Normal file
3986
lib/nvmf/fc.c
Normal file
File diff suppressed because it is too large
Load Diff
1681
lib/nvmf/fc_ls.c
Normal file
1681
lib/nvmf/fc_ls.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright (c) 2018 Broadcom. All Rights Reserved.
|
||||
* Copyright (c) 2018-2019 Broadcom. All Rights Reserved.
|
||||
* The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -34,6 +34,7 @@
|
||||
#ifndef __NVMF_FC_H__
|
||||
#define __NVMF_FC_H__
|
||||
|
||||
#include "spdk/nvme.h"
|
||||
#include "spdk/nvmf.h"
|
||||
#include "spdk/assert.h"
|
||||
#include "spdk/nvme_spec.h"
|
||||
@ -43,6 +44,16 @@
|
||||
#include "nvmf_internal.h"
|
||||
|
||||
#define SPDK_NVMF_FC_TR_ADDR_LEN 64
|
||||
#define NVMF_FC_INVALID_CONN_ID UINT64_MAX
|
||||
|
||||
#define SPDK_FC_HW_DUMP_REASON_STR_MAX_SIZE 256
|
||||
#define SPDK_MAX_NUM_OF_FC_PORTS 32
|
||||
#define SPDK_NVMF_PORT_ID_MAX_LEN 32
|
||||
|
||||
/*
|
||||
* FC HWQP pointer
|
||||
*/
|
||||
typedef void *spdk_nvmf_fc_lld_hwqp_t;
|
||||
|
||||
/*
|
||||
* FC HW port states.
|
||||
@ -59,7 +70,7 @@ enum spdk_fc_hwqp_state {
|
||||
};
|
||||
|
||||
/*
|
||||
* NVMF BCM FC Object state
|
||||
* NVMF FC Object state
|
||||
* Add all the generic states of the object here.
|
||||
* Specific object states can be added separately
|
||||
*/
|
||||
@ -86,25 +97,11 @@ enum spdk_nvmf_fc_request_state {
|
||||
SPDK_NVMF_FC_REQ_SUCCESS,
|
||||
SPDK_NVMF_FC_REQ_FAILED,
|
||||
SPDK_NVMF_FC_REQ_ABORTED,
|
||||
SPDK_NVMF_FC_REQ_BDEV_ABORTED,
|
||||
SPDK_NVMF_FC_REQ_PENDING,
|
||||
SPDK_NVMF_FC_REQ_MAX_STATE,
|
||||
};
|
||||
|
||||
/*
|
||||
* FC HWQP pointer
|
||||
*/
|
||||
typedef void *spdk_nvmf_fc_lld_hwqp_t;
|
||||
|
||||
/*
|
||||
* FC World Wide Name
|
||||
*/
|
||||
struct spdk_nvmf_fc_wwn {
|
||||
union {
|
||||
uint64_t wwn; /* World Wide Names consist of eight bytes */
|
||||
uint8_t octets[sizeof(uint64_t)];
|
||||
} u;
|
||||
};
|
||||
|
||||
/*
|
||||
* Generic DMA buffer descriptor
|
||||
*/
|
||||
@ -142,7 +139,7 @@ struct spdk_nvmf_fc_abts_ctx {
|
||||
* NVME FC transport errors
|
||||
*/
|
||||
struct spdk_nvmf_fc_errors {
|
||||
uint32_t no_xri;
|
||||
uint32_t no_xchg;
|
||||
uint32_t nport_invalid;
|
||||
uint32_t unknown_frame;
|
||||
uint32_t wqe_cmplt_err;
|
||||
@ -154,9 +151,7 @@ struct spdk_nvmf_fc_errors {
|
||||
uint32_t invalid_cq_type;
|
||||
uint32_t invalid_cq_id;
|
||||
uint32_t fc_req_buf_err;
|
||||
uint32_t aq_buf_alloc_err;
|
||||
uint32_t write_buf_alloc_err;
|
||||
uint32_t read_buf_alloc_err;
|
||||
uint32_t buf_alloc_err;
|
||||
uint32_t unexpected_err;
|
||||
uint32_t nvme_cmd_iu_err;
|
||||
uint32_t nvme_cmd_xfer_err;
|
||||
@ -173,10 +168,11 @@ struct spdk_nvmf_fc_errors {
|
||||
/*
|
||||
* Send Single Request/Response Sequence.
|
||||
*/
|
||||
struct spdk_nvmf_fc_send_srsr {
|
||||
struct spdk_nvmf_fc_buffer_desc rqst;
|
||||
struct spdk_nvmf_fc_buffer_desc rsp;
|
||||
struct spdk_nvmf_fc_buffer_desc sgl; /* Note: Len = (2 * bcm_sge_t) */
|
||||
struct spdk_nvmf_fc_srsr_bufs {
|
||||
void *rqst;
|
||||
size_t rqst_len;
|
||||
void *rsp;
|
||||
size_t rsp_len;
|
||||
uint16_t rpi;
|
||||
};
|
||||
|
||||
@ -210,6 +206,7 @@ struct spdk_nvmf_fc_nport {
|
||||
*/
|
||||
struct spdk_nvmf_fc_conn {
|
||||
struct spdk_nvmf_qpair qpair;
|
||||
struct spdk_nvme_transport_id trid;
|
||||
|
||||
uint64_t conn_id;
|
||||
struct spdk_nvmf_fc_hwqp *hwqp;
|
||||
@ -229,12 +226,11 @@ struct spdk_nvmf_fc_conn {
|
||||
/* number of read/write requests that are outstanding */
|
||||
uint16_t cur_fc_rw_depth;
|
||||
|
||||
/* requests that are waiting to obtain xri/buffer */
|
||||
/* requests that are waiting to obtain xchg/buffer */
|
||||
TAILQ_HEAD(, spdk_nvmf_fc_request) pending_queue;
|
||||
|
||||
struct spdk_nvmf_fc_association *fc_assoc;
|
||||
|
||||
/* additional FC info here - TBD */
|
||||
uint16_t rpi;
|
||||
|
||||
/* for association's connection list */
|
||||
@ -245,67 +241,70 @@ struct spdk_nvmf_fc_conn {
|
||||
|
||||
/* for hwqp's connection list */
|
||||
TAILQ_ENTRY(spdk_nvmf_fc_conn) link;
|
||||
|
||||
/* New QP create context. */
|
||||
struct nvmf_fc_ls_op_ctx *create_opd;
|
||||
};
|
||||
|
||||
/*
|
||||
* Structure for maintaining the XRI's
|
||||
* Structure for maintaining the FC exchanges
|
||||
*/
|
||||
struct spdk_nvmf_fc_xri {
|
||||
uint32_t xri; /* The actual xri value */
|
||||
struct spdk_nvmf_fc_xchg {
|
||||
uint32_t xchg_id; /* The actual xchg identifier */
|
||||
|
||||
/* Internal */
|
||||
TAILQ_ENTRY(spdk_nvmf_fc_xri) link;
|
||||
bool is_active;
|
||||
TAILQ_ENTRY(spdk_nvmf_fc_xchg) link;
|
||||
bool active;
|
||||
bool aborted;
|
||||
bool send_abts; /* Valid if is_aborted is set. */
|
||||
};
|
||||
|
||||
struct spdk_nvmf_fc_poll_group;
|
||||
/*
|
||||
* FC poll group structure
|
||||
*/
|
||||
struct spdk_nvmf_fc_poll_group {
|
||||
struct spdk_nvmf_transport_poll_group tp_poll_group;
|
||||
struct spdk_nvmf_poll_group *poll_group;
|
||||
struct spdk_nvmf_tgt *nvmf_tgt;
|
||||
struct spdk_nvmf_fc_transport *fc_transport;
|
||||
uint32_t hwqp_count; /* number of hwqp's assigned to this pg */
|
||||
TAILQ_HEAD(, spdk_nvmf_fc_hwqp) hwqp_list;
|
||||
|
||||
TAILQ_ENTRY(spdk_nvmf_fc_poll_group) link;
|
||||
};
|
||||
|
||||
/*
|
||||
* HWQP poller structure passed from Master thread
|
||||
*/
|
||||
struct spdk_nvmf_fc_hwqp {
|
||||
enum spdk_fc_hwqp_state state; /* queue state (for poller) */
|
||||
uint32_t lcore_id; /* core hwqp is running on (for tracing purposes only) */
|
||||
struct spdk_thread *thread; /* thread hwqp is running on */
|
||||
uint32_t hwqp_id; /* A unique id (per physical port) for a hwqp */
|
||||
uint32_t rq_size; /* receive queue size */
|
||||
spdk_nvmf_fc_lld_hwqp_t queues; /* vendor HW queue set */
|
||||
spdk_nvmf_fc_lld_hwqp_t queues; /* vendor HW queue set */
|
||||
struct spdk_nvmf_fc_port *fc_port; /* HW port structure for these queues */
|
||||
struct spdk_nvmf_fc_poll_group *poll_group;
|
||||
|
||||
void *context; /* Vendor Context */
|
||||
struct spdk_nvmf_fc_poll_group *fc_poll_group;
|
||||
|
||||
/* qpair (fc_connection) list */
|
||||
TAILQ_HEAD(, spdk_nvmf_fc_conn) connection_list;
|
||||
uint32_t num_conns; /* number of connections to queue */
|
||||
uint16_t cid_cnt; /* used to generate unique conn. id for RQ */
|
||||
uint32_t free_q_slots; /* free q slots available for connections */
|
||||
enum spdk_fc_hwqp_state state; /* Poller state (e.g. online, offline) */
|
||||
|
||||
/* Internal */
|
||||
struct spdk_mempool *fc_request_pool;
|
||||
struct spdk_nvmf_fc_request *fc_reqs_buf;
|
||||
TAILQ_HEAD(, spdk_nvmf_fc_request) free_reqs;
|
||||
TAILQ_HEAD(, spdk_nvmf_fc_request) in_use_reqs;
|
||||
|
||||
TAILQ_HEAD(, spdk_nvmf_fc_xri) pending_xri_list;
|
||||
|
||||
struct spdk_nvmf_fc_errors counters;
|
||||
uint32_t send_frame_xri;
|
||||
uint8_t send_frame_seqid;
|
||||
|
||||
/* Pending LS request waiting for XRI. */
|
||||
/* Pending LS request waiting for FC resource */
|
||||
TAILQ_HEAD(, spdk_nvmf_fc_ls_rqst) ls_pending_queue;
|
||||
|
||||
/* Sync req list */
|
||||
TAILQ_HEAD(, spdk_nvmf_fc_poller_api_queue_sync_args) sync_cbs;
|
||||
|
||||
TAILQ_ENTRY(spdk_nvmf_fc_hwqp) link;
|
||||
};
|
||||
|
||||
struct spdk_nvmf_fc_ls_rsrc_pool {
|
||||
void *assocs_mptr;
|
||||
uint32_t assocs_count;
|
||||
TAILQ_HEAD(, spdk_nvmf_fc_association) assoc_free_list;
|
||||
|
||||
void *conns_mptr;
|
||||
uint32_t conns_count;
|
||||
TAILQ_HEAD(, spdk_nvmf_fc_conn) fc_conn_free_list;
|
||||
void *context; /* Vendor specific context data */
|
||||
};
|
||||
|
||||
/*
|
||||
@ -314,11 +313,10 @@ struct spdk_nvmf_fc_ls_rsrc_pool {
|
||||
struct spdk_nvmf_fc_port {
|
||||
uint8_t port_hdl;
|
||||
enum spdk_fc_port_state hw_port_status;
|
||||
uint32_t xri_base;
|
||||
uint32_t xri_count;
|
||||
uint16_t fcp_rq_id;
|
||||
struct spdk_ring *xri_ring;
|
||||
struct spdk_nvmf_fc_hwqp ls_queue;
|
||||
new_qpair_fn new_qp_cb;
|
||||
|
||||
uint32_t num_io_queues;
|
||||
struct spdk_nvmf_fc_hwqp *io_queues;
|
||||
/*
|
||||
@ -328,8 +326,7 @@ struct spdk_nvmf_fc_port {
|
||||
int num_nports;
|
||||
TAILQ_ENTRY(spdk_nvmf_fc_port) link;
|
||||
|
||||
struct spdk_nvmf_fc_ls_rsrc_pool ls_rsrc_pool;
|
||||
struct spdk_mempool *io_rsrc_pool; /* Pools to store bdev_io's for this port */
|
||||
struct spdk_mempool *io_resource_pool; /* Pools to store bdev_io's for this port */
|
||||
void *port_ctx;
|
||||
};
|
||||
|
||||
@ -342,7 +339,7 @@ struct spdk_nvmf_fc_request {
|
||||
uint32_t poller_lcore; /* for tracing purposes only */
|
||||
struct spdk_thread *poller_thread;
|
||||
uint16_t buf_index;
|
||||
struct spdk_nvmf_fc_xri *xri;
|
||||
struct spdk_nvmf_fc_xchg *xchg;
|
||||
uint16_t oxid;
|
||||
uint16_t rpi;
|
||||
struct spdk_nvmf_fc_conn *fc_conn;
|
||||
@ -353,6 +350,8 @@ struct spdk_nvmf_fc_request {
|
||||
uint32_t magic;
|
||||
uint32_t s_id;
|
||||
uint32_t d_id;
|
||||
void *buffers[SPDK_NVMF_MAX_SGL_ENTRIES];
|
||||
bool data_from_pool;
|
||||
TAILQ_ENTRY(spdk_nvmf_fc_request) link;
|
||||
TAILQ_ENTRY(spdk_nvmf_fc_request) pending_link;
|
||||
TAILQ_HEAD(, spdk_nvmf_fc_caller_ctx) abort_cbs;
|
||||
@ -361,6 +360,7 @@ struct spdk_nvmf_fc_request {
|
||||
SPDK_STATIC_ASSERT(!offsetof(struct spdk_nvmf_fc_request, req),
|
||||
"FC request and NVMF request address don't match.");
|
||||
|
||||
|
||||
/*
|
||||
* NVMF FC Association
|
||||
*/
|
||||
@ -370,7 +370,6 @@ struct spdk_nvmf_fc_association {
|
||||
struct spdk_nvmf_fc_nport *tgtport;
|
||||
struct spdk_nvmf_fc_remote_port_info *rport;
|
||||
struct spdk_nvmf_subsystem *subsystem;
|
||||
struct spdk_nvmf_host *host;
|
||||
enum spdk_nvmf_fc_object_state assoc_state;
|
||||
|
||||
char host_id[FCNVME_ASSOC_HOSTID_LEN];
|
||||
@ -392,8 +391,8 @@ struct spdk_nvmf_fc_association {
|
||||
|
||||
void *ls_del_op_ctx; /* delete assoc. callback list */
|
||||
|
||||
/* req/resp buffers used to send disconnect to initiator */
|
||||
struct spdk_nvmf_fc_send_srsr snd_disconn_bufs;
|
||||
/* disconnect cmd buffers (sent to initiator) */
|
||||
struct spdk_nvmf_fc_srsr_bufs *snd_disconn_bufs;
|
||||
};
|
||||
|
||||
/*
|
||||
@ -430,10 +429,13 @@ enum spdk_nvmf_fc_poller_api {
|
||||
SPDK_NVMF_FC_POLLER_API_QUIESCE_QUEUE,
|
||||
SPDK_NVMF_FC_POLLER_API_ACTIVATE_QUEUE,
|
||||
SPDK_NVMF_FC_POLLER_API_ABTS_RECEIVED,
|
||||
SPDK_NVMF_FC_POLLER_API_REQ_ABORT_COMPLETE,
|
||||
SPDK_NVMF_FC_POLLER_API_ADAPTER_EVENT,
|
||||
SPDK_NVMF_FC_POLLER_API_AEN,
|
||||
SPDK_NVMF_FC_POLLER_API_QUEUE_SYNC,
|
||||
SPDK_NVMF_FC_POLLER_API_QUEUE_SYNC_DONE,
|
||||
SPDK_NVMF_FC_POLLER_API_ADD_HWQP,
|
||||
SPDK_NVMF_FC_POLLER_API_REMOVE_HWQP,
|
||||
};
|
||||
|
||||
/*
|
||||
@ -445,6 +447,7 @@ typedef void (*spdk_nvmf_fc_poller_api_cb)(void *cb_data, enum spdk_nvmf_fc_poll
|
||||
* Poller API callback data
|
||||
*/
|
||||
struct spdk_nvmf_fc_poller_api_cb_info {
|
||||
struct spdk_thread *cb_thread;
|
||||
spdk_nvmf_fc_poller_api_cb cb_func;
|
||||
void *cb_data;
|
||||
enum spdk_nvmf_fc_poller_api_ret ret;
|
||||
@ -465,6 +468,7 @@ struct spdk_nvmf_fc_poller_api_del_connection_args {
|
||||
bool send_abts;
|
||||
/* internal */
|
||||
int fc_request_cnt;
|
||||
bool backend_initiated;
|
||||
};
|
||||
|
||||
struct spdk_nvmf_fc_poller_api_quiesce_queue_args {
|
||||
@ -486,6 +490,7 @@ struct spdk_nvmf_fc_poller_api_abts_recvd_args {
|
||||
|
||||
struct spdk_nvmf_fc_poller_api_queue_sync_done_args {
|
||||
struct spdk_nvmf_fc_hwqp *hwqp;
|
||||
struct spdk_nvmf_fc_poller_api_cb_info cb_info;
|
||||
uint64_t tag;
|
||||
};
|
||||
|
||||
@ -498,7 +503,7 @@ struct spdk_nvmf_fc_ls_rqst {
|
||||
uint32_t rqst_len;
|
||||
uint32_t rsp_len;
|
||||
uint32_t rpi;
|
||||
struct spdk_nvmf_fc_xri *xri;
|
||||
struct spdk_nvmf_fc_xchg *xchg;
|
||||
uint16_t oxid;
|
||||
void *private_data; /* for LLD only (LS does not touch) */
|
||||
TAILQ_ENTRY(spdk_nvmf_fc_ls_rqst) ls_pending_link;
|
||||
@ -525,6 +530,48 @@ struct __attribute__((__packed__)) spdk_nvmf_fc_rq_buf_ls_request {
|
||||
SPDK_STATIC_ASSERT(sizeof(struct spdk_nvmf_fc_rq_buf_ls_request) ==
|
||||
FCNVME_MAX_LS_BUFFER_SIZE, "LS RQ Buffer overflow");
|
||||
|
||||
/* Poller API structures (arguments and callback data */
|
||||
typedef void (*spdk_nvmf_fc_del_assoc_cb)(void *arg, uint32_t err);
|
||||
|
||||
struct spdk_nvmf_fc_ls_add_conn_api_data {
|
||||
struct spdk_nvmf_fc_poller_api_add_connection_args args;
|
||||
struct spdk_nvmf_fc_ls_rqst *ls_rqst;
|
||||
struct spdk_nvmf_fc_association *assoc;
|
||||
bool aq_conn; /* true if adding connection for new association */
|
||||
};
|
||||
|
||||
/* Disconnect (connection) request functions */
|
||||
struct spdk_nvmf_fc_ls_del_conn_api_data {
|
||||
struct spdk_nvmf_fc_poller_api_del_connection_args args;
|
||||
struct spdk_nvmf_fc_ls_rqst *ls_rqst;
|
||||
struct spdk_nvmf_fc_association *assoc;
|
||||
bool aq_conn; /* true if deleting AQ connection */
|
||||
};
|
||||
|
||||
/* used by LS disconnect association cmd handling */
|
||||
struct spdk_nvmf_fc_ls_disconn_assoc_api_data {
|
||||
struct spdk_nvmf_fc_nport *tgtport;
|
||||
struct spdk_nvmf_fc_ls_rqst *ls_rqst;
|
||||
};
|
||||
|
||||
/* used by delete association call */
|
||||
struct spdk_nvmf_fc_delete_assoc_api_data {
|
||||
struct spdk_nvmf_fc_poller_api_del_connection_args args;
|
||||
struct spdk_nvmf_fc_association *assoc;
|
||||
bool from_ls_rqst; /* true = request came for LS */
|
||||
spdk_nvmf_fc_del_assoc_cb del_assoc_cb;
|
||||
void *del_assoc_cb_data;
|
||||
};
|
||||
|
||||
struct nvmf_fc_ls_op_ctx {
|
||||
union {
|
||||
struct spdk_nvmf_fc_ls_add_conn_api_data add_conn;
|
||||
struct spdk_nvmf_fc_ls_del_conn_api_data del_conn;
|
||||
struct spdk_nvmf_fc_ls_disconn_assoc_api_data disconn_assoc;
|
||||
struct spdk_nvmf_fc_delete_assoc_api_data del_assoc;
|
||||
} u;
|
||||
struct nvmf_fc_ls_op_ctx *next_op_ctx;
|
||||
};
|
||||
|
||||
struct spdk_nvmf_fc_poller_api_queue_sync_args {
|
||||
uint64_t u_id;
|
||||
@ -535,6 +582,185 @@ struct spdk_nvmf_fc_poller_api_queue_sync_args {
|
||||
TAILQ_ENTRY(spdk_nvmf_fc_poller_api_queue_sync_args) link;
|
||||
};
|
||||
|
||||
/**
|
||||
* Following defines and structures are used to pass messages between master thread
|
||||
* and FCT driver.
|
||||
*/
|
||||
enum spdk_fc_event {
|
||||
SPDK_FC_HW_PORT_INIT,
|
||||
SPDK_FC_HW_PORT_ONLINE,
|
||||
SPDK_FC_HW_PORT_OFFLINE,
|
||||
SPDK_FC_HW_PORT_RESET,
|
||||
SPDK_FC_NPORT_CREATE,
|
||||
SPDK_FC_NPORT_DELETE,
|
||||
SPDK_FC_IT_ADD, /* PRLI */
|
||||
SPDK_FC_IT_DELETE, /* PRLI */
|
||||
SPDK_FC_ABTS_RECV,
|
||||
SPDK_FC_LINK_BREAK,
|
||||
SPDK_FC_HW_PORT_DUMP,
|
||||
SPDK_FC_UNRECOVERABLE_ERR,
|
||||
SPDK_FC_EVENT_MAX,
|
||||
};
|
||||
|
||||
/**
|
||||
* Arguments for to dump assoc id
|
||||
*/
|
||||
struct spdk_nvmf_fc_dump_assoc_id_args {
|
||||
uint8_t pport_handle;
|
||||
uint16_t nport_handle;
|
||||
uint32_t assoc_id;
|
||||
};
|
||||
|
||||
/**
|
||||
* Arguments for HW port init event.
|
||||
*/
|
||||
struct spdk_nvmf_fc_hw_port_init_args {
|
||||
uint32_t ls_queue_size;
|
||||
spdk_nvmf_fc_lld_hwqp_t ls_queue;
|
||||
uint32_t io_queue_size;
|
||||
uint32_t io_queue_cnt;
|
||||
spdk_nvmf_fc_lld_hwqp_t *io_queues;
|
||||
void *cb_ctx;
|
||||
void *port_ctx;
|
||||
uint8_t port_handle;
|
||||
uint8_t nvme_aq_index; /* io_queue used for nvme admin queue */
|
||||
uint16_t fcp_rq_id; /* Base rq ID of SCSI queue */
|
||||
};
|
||||
|
||||
/**
|
||||
* Arguments for HW port link break event.
|
||||
*/
|
||||
struct spdk_nvmf_hw_port_link_break_args {
|
||||
uint8_t port_handle;
|
||||
void *cb_ctx;
|
||||
};
|
||||
|
||||
/**
|
||||
* Arguments for HW port online event.
|
||||
*/
|
||||
struct spdk_nvmf_fc_hw_port_online_args {
|
||||
uint8_t port_handle;
|
||||
void *cb_ctx;
|
||||
};
|
||||
|
||||
/**
|
||||
* Arguments for HW port offline event.
|
||||
*/
|
||||
struct spdk_nvmf_fc_hw_port_offline_args {
|
||||
uint8_t port_handle;
|
||||
void *cb_ctx;
|
||||
};
|
||||
|
||||
/**
|
||||
* Arguments for n-port add event.
|
||||
*/
|
||||
struct spdk_nvmf_fc_nport_create_args {
|
||||
uint8_t port_handle;
|
||||
uint16_t nport_handle;
|
||||
struct spdk_uuid container_uuid; /* UUID of the nports container */
|
||||
struct spdk_uuid nport_uuid; /* Unique UUID for the nport */
|
||||
uint32_t d_id;
|
||||
struct spdk_nvmf_fc_wwn fc_nodename;
|
||||
struct spdk_nvmf_fc_wwn fc_portname;
|
||||
uint32_t subsys_id; /* Subsystemid */
|
||||
char port_id[SPDK_NVMF_PORT_ID_MAX_LEN];
|
||||
void *cb_ctx;
|
||||
};
|
||||
|
||||
/**
|
||||
* Arguments for n-port delete event.
|
||||
*/
|
||||
struct spdk_nvmf_fc_nport_delete_args {
|
||||
uint8_t port_handle;
|
||||
uint32_t nport_handle;
|
||||
uint32_t subsys_id; /* Subsystem id */
|
||||
void *cb_ctx;
|
||||
};
|
||||
|
||||
/**
|
||||
* Arguments for I_T add event.
|
||||
*/
|
||||
struct spdk_nvmf_fc_hw_i_t_add_args {
|
||||
uint8_t port_handle;
|
||||
uint32_t nport_handle;
|
||||
uint16_t itn_handle;
|
||||
uint32_t rpi;
|
||||
uint32_t s_id;
|
||||
uint32_t initiator_prli_info;
|
||||
uint32_t target_prli_info; /* populated by the SPDK master */
|
||||
struct spdk_nvmf_fc_wwn fc_nodename;
|
||||
struct spdk_nvmf_fc_wwn fc_portname;
|
||||
void *cb_ctx;
|
||||
};
|
||||
|
||||
/**
|
||||
* Arguments for I_T delete event.
|
||||
*/
|
||||
struct spdk_nvmf_fc_hw_i_t_delete_args {
|
||||
uint8_t port_handle;
|
||||
uint32_t nport_handle;
|
||||
uint16_t itn_handle; /* Only used by FC LLD driver; unused in SPDK */
|
||||
uint32_t rpi;
|
||||
uint32_t s_id;
|
||||
void *cb_ctx;
|
||||
};
|
||||
|
||||
/**
|
||||
* Arguments for ABTS event.
|
||||
*/
|
||||
struct spdk_nvmf_fc_abts_args {
|
||||
uint8_t port_handle;
|
||||
uint32_t nport_handle;
|
||||
uint32_t rpi;
|
||||
uint16_t oxid, rxid;
|
||||
void *cb_ctx;
|
||||
};
|
||||
|
||||
/**
|
||||
* Arguments for link break event.
|
||||
*/
|
||||
struct spdk_nvmf_fc_link_break_args {
|
||||
uint8_t port_handle;
|
||||
};
|
||||
|
||||
/**
|
||||
* Arguments for port reset event.
|
||||
*/
|
||||
struct spdk_nvmf_fc_hw_port_reset_args {
|
||||
uint8_t port_handle;
|
||||
bool dump_queues;
|
||||
char reason[SPDK_FC_HW_DUMP_REASON_STR_MAX_SIZE];
|
||||
uint32_t **dump_buf;
|
||||
void *cb_ctx;
|
||||
};
|
||||
|
||||
/**
|
||||
* Arguments for unrecoverable error event
|
||||
*/
|
||||
struct spdk_nvmf_fc_unrecoverable_error_event_args {
|
||||
};
|
||||
|
||||
/**
|
||||
* Callback function to the FCT driver.
|
||||
*/
|
||||
typedef void (*spdk_nvmf_fc_callback)(uint8_t port_handle,
|
||||
enum spdk_fc_event event_type,
|
||||
void *arg, int err);
|
||||
|
||||
/**
|
||||
* Enqueue an FCT event to master thread
|
||||
*
|
||||
* \param event_type Type of the event.
|
||||
* \param args Pointer to the argument structure.
|
||||
* \param cb_func Callback function into fc driver.
|
||||
*
|
||||
* \return 0 on success, non-zero on failure.
|
||||
*/
|
||||
int
|
||||
spdk_nvmf_fc_master_enqueue_event(enum spdk_fc_event event_type,
|
||||
void *args,
|
||||
spdk_nvmf_fc_callback cb_func);
|
||||
|
||||
/*
|
||||
* dump info
|
||||
*/
|
||||
@ -578,79 +804,16 @@ struct spdk_nvmf_fc_caller_ctx {
|
||||
};
|
||||
|
||||
/*
|
||||
* Low level FC driver function table (functions provided by vendor FC device driver)
|
||||
* NVMF FC Exchange Info (for debug)
|
||||
*/
|
||||
struct spdk_nvmf_fc_ll_drvr_ops {
|
||||
|
||||
/* initialize the low level driver */
|
||||
int (*lld_init)(void);
|
||||
|
||||
/* low level driver finish */
|
||||
void (*lld_fini)(void);
|
||||
|
||||
/* initialize hw queues */
|
||||
int (*init_q)(struct spdk_nvmf_fc_hwqp *hwqp);
|
||||
|
||||
void (*reinit_q)(spdk_nvmf_fc_lld_hwqp_t queues_prev,
|
||||
spdk_nvmf_fc_lld_hwqp_t queues_curr);
|
||||
|
||||
/* initialize hw queue buffers */
|
||||
int (*init_q_buffers)(struct spdk_nvmf_fc_hwqp *hwqp);
|
||||
|
||||
/* poll the hw queues for requests */
|
||||
uint32_t (*poll_queue)(struct spdk_nvmf_fc_hwqp *hwqp);
|
||||
|
||||
/* receive data (for data-in requests) */
|
||||
int (*recv_data)(struct spdk_nvmf_fc_request *fc_req);
|
||||
|
||||
/* send data (for data-out requests) */
|
||||
int (*send_data)(struct spdk_nvmf_fc_request *fc_req);
|
||||
|
||||
/* release hw queust buffer */
|
||||
void (*q_buffer_release)(struct spdk_nvmf_fc_hwqp *hwqp, uint16_t buff_idx);
|
||||
|
||||
/* transmist nvme response */
|
||||
int (*xmt_rsp)(struct spdk_nvmf_fc_request *fc_req, uint8_t *ersp_buf, uint32_t ersp_len);
|
||||
|
||||
/* transmist LS response */
|
||||
int (*xmt_ls_rsp)(struct spdk_nvmf_fc_nport *tgtport, struct spdk_nvmf_fc_ls_rqst *ls_rqst);
|
||||
|
||||
/* issue abts */
|
||||
int (*issue_abort)(struct spdk_nvmf_fc_hwqp *hwqp, struct spdk_nvmf_fc_xri *xri,
|
||||
bool send_abts, spdk_nvmf_fc_caller_cb cb, void *cb_args);
|
||||
|
||||
/* transmit abts response */
|
||||
int (*xmt_bls_rsp)(struct spdk_nvmf_fc_hwqp *hwqp, uint16_t ox_id, uint16_t rx_id, uint16_t rpi,
|
||||
bool rjt, uint8_t rjt_exp, spdk_nvmf_fc_caller_cb cb, void *cb_args);
|
||||
|
||||
/* transmit single request - single response */
|
||||
int (*xmt_srsr_req)(struct spdk_nvmf_fc_hwqp *hwqp, struct spdk_nvmf_fc_send_srsr *srsr,
|
||||
spdk_nvmf_fc_caller_cb cb, void *cb_args);
|
||||
|
||||
/* issue queue marker (abts processing) */
|
||||
int (*issue_q_marker)(struct spdk_nvmf_fc_hwqp *hwqp, uint64_t u_id, uint16_t skip_rq);
|
||||
|
||||
/* assign a new connection to a hwqp (return connection ID) */
|
||||
struct spdk_nvmf_fc_hwqp *(*assign_conn_to_hwqp)(
|
||||
struct spdk_nvmf_fc_hwqp *queues, uint32_t num_queues,
|
||||
uint64_t *conn_id, uint32_t sq_size, bool for_aq);
|
||||
|
||||
/* get the hwqp from the given connection id */
|
||||
struct spdk_nvmf_fc_hwqp *(*get_hwqp_from_conn_id)(struct spdk_nvmf_fc_hwqp *hwqp,
|
||||
uint32_t num_queues, uint64_t conn_id);
|
||||
|
||||
/* release connection ID (done with using it) */
|
||||
void (*release_conn)(struct spdk_nvmf_fc_hwqp *hwqp, uint64_t conn_id, uint32_t sq_size);
|
||||
|
||||
/* dump all queue info into dump_info */
|
||||
void (*dump_all_queues)(struct spdk_nvmf_fc_hwqp *ls_queues,
|
||||
struct spdk_nvmf_fc_hwqp *io_queues,
|
||||
uint32_t num_queues,
|
||||
struct spdk_nvmf_fc_queue_dump_info *dump_info);
|
||||
struct spdk_nvmf_fc_xchg_info {
|
||||
uint32_t xchg_base;
|
||||
uint32_t xchg_total_count;
|
||||
uint32_t xchg_avail_count;
|
||||
uint32_t send_frame_xchg_id;
|
||||
uint8_t send_frame_seqid;
|
||||
};
|
||||
|
||||
extern struct spdk_nvmf_fc_ll_drvr_ops spdk_nvmf_fc_lld_ops;
|
||||
|
||||
/*
|
||||
* NVMF FC inline and function prototypes
|
||||
*/
|
||||
@ -688,41 +851,39 @@ spdk_nvmf_fc_req_in_xfer(struct spdk_nvmf_fc_request *fc_req)
|
||||
}
|
||||
}
|
||||
|
||||
typedef void (*spdk_nvmf_fc_del_assoc_cb)(void *arg, uint32_t err);
|
||||
int spdk_nvmf_fc_delete_association(struct spdk_nvmf_fc_nport *tgtport,
|
||||
uint64_t assoc_id, bool send_abts,
|
||||
spdk_nvmf_fc_del_assoc_cb del_assoc_cb,
|
||||
void *cb_data);
|
||||
static inline void
|
||||
spdk_nvmf_fc_create_trid(struct spdk_nvme_transport_id *trid, uint64_t n_wwn, uint64_t p_wwn)
|
||||
{
|
||||
trid->trtype = (enum spdk_nvme_transport_type) SPDK_NVMF_TRTYPE_FC;
|
||||
trid->adrfam = SPDK_NVMF_ADRFAM_FC;
|
||||
snprintf(trid->trsvcid, sizeof(trid->trsvcid), "none");
|
||||
snprintf(trid->traddr, sizeof(trid->traddr), "nn-0x%lx:pn-0x%lx", n_wwn, p_wwn);
|
||||
}
|
||||
|
||||
void spdk_nvmf_fc_ls_init(struct spdk_nvmf_fc_port *fc_port);
|
||||
|
||||
void spdk_nvmf_fc_ls_fini(struct spdk_nvmf_fc_port *fc_port);
|
||||
|
||||
struct spdk_nvmf_fc_port *spdk_nvmf_fc_port_list_get(uint8_t port_hdl);
|
||||
void spdk_nvmf_fc_handle_ls_rqst(struct spdk_nvmf_fc_ls_rqst *ls_rqst);
|
||||
void nvmf_fc_ls_add_conn_failure(
|
||||
struct spdk_nvmf_fc_association *assoc,
|
||||
struct spdk_nvmf_fc_ls_rqst *ls_rqst,
|
||||
struct spdk_nvmf_fc_conn *fc_conn,
|
||||
bool aq_conn);
|
||||
|
||||
int spdk_nvmf_fc_nport_set_state(struct spdk_nvmf_fc_nport *nport,
|
||||
enum spdk_nvmf_fc_object_state state);
|
||||
int spdk_nvmf_fc_xmt_ls_rsp(struct spdk_nvmf_fc_nport *tgtport,
|
||||
struct spdk_nvmf_fc_ls_rqst *ls_rqst);
|
||||
|
||||
int spdk_nvmf_fc_assoc_set_state(struct spdk_nvmf_fc_association *assoc,
|
||||
enum spdk_nvmf_fc_object_state state);
|
||||
|
||||
bool spdk_nvmf_fc_nport_add_rem_port(struct spdk_nvmf_fc_nport *nport,
|
||||
struct spdk_nvmf_fc_remote_port_info *rem_port);
|
||||
|
||||
bool spdk_nvmf_fc_nport_remove_rem_port(struct spdk_nvmf_fc_nport *nport,
|
||||
struct spdk_nvmf_fc_remote_port_info *rem_port);
|
||||
void spdk_nvmf_fc_init_hwqp(struct spdk_nvmf_fc_port *fc_port, struct spdk_nvmf_fc_hwqp *hwqp);
|
||||
|
||||
void spdk_nvmf_fc_init_poller_queues(struct spdk_nvmf_fc_hwqp *hwqp);
|
||||
|
||||
void spdk_nvmf_fc_reinit_poller_queues(struct spdk_nvmf_fc_hwqp *hwqp,
|
||||
void *queues_curr);
|
||||
struct spdk_nvmf_fc_conn *spdk_nvmf_fc_hwqp_find_fc_conn(struct spdk_nvmf_fc_hwqp *hwqp,
|
||||
uint64_t conn_id);
|
||||
|
||||
void spdk_nvmf_fc_init_poller(struct spdk_nvmf_fc_port *fc_port,
|
||||
struct spdk_nvmf_fc_hwqp *hwqp);
|
||||
void spdk_nvmf_fc_hwqp_reinit_poller_queues(struct spdk_nvmf_fc_hwqp *hwqp, void *queues_curr);
|
||||
|
||||
void spdk_nvmf_fc_add_hwqp_to_poller(struct spdk_nvmf_fc_hwqp *hwqp, bool admin_q);
|
||||
|
||||
void spdk_nvmf_fc_remove_hwqp_from_poller(struct spdk_nvmf_fc_hwqp *hwqp);
|
||||
struct spdk_nvmf_fc_port *spdk_nvmf_fc_port_lookup(uint8_t port_hdl);
|
||||
|
||||
bool spdk_nvmf_fc_port_is_offline(struct spdk_nvmf_fc_port *fc_port);
|
||||
|
||||
@ -732,81 +893,72 @@ bool spdk_nvmf_fc_port_is_online(struct spdk_nvmf_fc_port *fc_port);
|
||||
|
||||
int spdk_nvmf_fc_port_set_online(struct spdk_nvmf_fc_port *fc_port);
|
||||
|
||||
int spdk_nvmf_fc_hwqp_port_set_online(struct spdk_nvmf_fc_hwqp *hwqp);
|
||||
|
||||
int spdk_nvmf_fc_hwqp_port_set_offline(struct spdk_nvmf_fc_hwqp *hwqp);
|
||||
|
||||
int spdk_nvmf_fc_rport_set_state(struct spdk_nvmf_fc_remote_port_info *rport,
|
||||
enum spdk_nvmf_fc_object_state state);
|
||||
|
||||
void spdk_nvmf_fc_port_list_add(struct spdk_nvmf_fc_port *fc_port);
|
||||
|
||||
struct spdk_nvmf_fc_nport *spdk_nvmf_fc_nport_get(uint8_t port_hdl, uint16_t nport_hdl);
|
||||
void spdk_nvmf_fc_port_add(struct spdk_nvmf_fc_port *fc_port);
|
||||
|
||||
int spdk_nvmf_fc_port_add_nport(struct spdk_nvmf_fc_port *fc_port,
|
||||
struct spdk_nvmf_fc_nport *nport);
|
||||
|
||||
uint32_t spdk_nvmf_fc_nport_get_association_count(struct spdk_nvmf_fc_nport *nport);
|
||||
|
||||
int spdk_nvmf_fc_port_remove_nport(struct spdk_nvmf_fc_port *fc_port,
|
||||
struct spdk_nvmf_fc_nport *nport);
|
||||
|
||||
struct spdk_nvmf_fc_nport *spdk_nvmf_fc_nport_find(uint8_t port_hdl, uint16_t nport_hdl);
|
||||
|
||||
int spdk_nvmf_fc_nport_set_state(struct spdk_nvmf_fc_nport *nport,
|
||||
enum spdk_nvmf_fc_object_state state);
|
||||
|
||||
bool spdk_nvmf_fc_nport_add_rem_port(struct spdk_nvmf_fc_nport *nport,
|
||||
struct spdk_nvmf_fc_remote_port_info *rem_port);
|
||||
|
||||
bool spdk_nvmf_fc_nport_remove_rem_port(struct spdk_nvmf_fc_nport *nport,
|
||||
struct spdk_nvmf_fc_remote_port_info *rem_port);
|
||||
|
||||
bool spdk_nvmf_fc_nport_has_no_rport(struct spdk_nvmf_fc_nport *nport);
|
||||
|
||||
int spdk_nvmf_fc_assoc_set_state(struct spdk_nvmf_fc_association *assoc,
|
||||
enum spdk_nvmf_fc_object_state state);
|
||||
|
||||
int spdk_nvmf_fc_delete_association(struct spdk_nvmf_fc_nport *tgtport,
|
||||
uint64_t assoc_id, bool send_abts, bool backend_initiated,
|
||||
spdk_nvmf_fc_del_assoc_cb del_assoc_cb,
|
||||
void *cb_data);
|
||||
|
||||
bool spdk_nvmf_ctrlr_is_on_nport(uint8_t port_hdl, uint16_t nport_hdl,
|
||||
struct spdk_nvmf_ctrlr *ctrlr);
|
||||
|
||||
void spdk_nvmf_fc_assign_queue_to_master_thread(struct spdk_nvmf_fc_hwqp *hwqp);
|
||||
|
||||
void spdk_nvmf_fc_poll_group_add_hwqp(struct spdk_nvmf_fc_hwqp *hwqp);
|
||||
|
||||
void spdk_nvmf_fc_poll_group_remove_hwqp(struct spdk_nvmf_fc_hwqp *hwqp);
|
||||
|
||||
int spdk_nvmf_fc_hwqp_set_online(struct spdk_nvmf_fc_hwqp *hwqp);
|
||||
|
||||
int spdk_nvmf_fc_hwqp_set_offline(struct spdk_nvmf_fc_hwqp *hwqp);
|
||||
|
||||
uint32_t spdk_nvmf_fc_get_prli_service_params(void);
|
||||
|
||||
bool spdk_nvmf_fc_nport_is_rport_empty(struct spdk_nvmf_fc_nport *nport);
|
||||
|
||||
void spdk_nvmf_fc_handle_abts_frame(struct spdk_nvmf_fc_nport *nport,
|
||||
uint16_t rpi, uint16_t oxid,
|
||||
void spdk_nvmf_fc_handle_abts_frame(struct spdk_nvmf_fc_nport *nport, uint16_t rpi, uint16_t oxid,
|
||||
uint16_t rxid);
|
||||
|
||||
void spdk_nvmf_fc_request_abort(struct spdk_nvmf_fc_request *fc_req, bool send_abts,
|
||||
spdk_nvmf_fc_caller_cb cb, void *cb_args);
|
||||
|
||||
int spdk_nvmf_fc_xmt_srsr_req(struct spdk_nvmf_fc_hwqp *hwqp,
|
||||
struct spdk_nvmf_fc_srsr_bufs *srsr_bufs,
|
||||
spdk_nvmf_fc_caller_cb cb, void *cb_args);
|
||||
|
||||
struct spdk_nvmf_tgt *spdk_nvmf_fc_get_tgt(void);
|
||||
|
||||
void spdk_nvmf_fc_dump_all_queues(struct spdk_nvmf_fc_port *fc_port,
|
||||
struct spdk_nvmf_fc_queue_dump_info *dump_info);
|
||||
|
||||
void spdk_nvmf_fc_handle_ls_rqst(struct spdk_nvmf_fc_ls_rqst *ls_rqst);
|
||||
|
||||
int spdk_nvmf_fc_xmt_ls_rsp(struct spdk_nvmf_fc_nport *tgtport,
|
||||
struct spdk_nvmf_fc_ls_rqst *ls_rqst);
|
||||
|
||||
struct spdk_nvmf_fc_nport *spdk_nvmf_bcm_req_fc_nport_get(struct spdk_nvmf_request *req);
|
||||
|
||||
struct spdk_nvmf_fc_association *spdk_nvmf_fc_get_ctrlr_assoc(struct spdk_nvmf_ctrlr *ctrlr);
|
||||
|
||||
bool spdk_nvmf_fc_nport_is_association_empty(struct spdk_nvmf_fc_nport *nport);
|
||||
|
||||
int spdk_nvmf_fc_xmt_srsr_req(struct spdk_nvmf_fc_hwqp *hwqp,
|
||||
struct spdk_nvmf_fc_send_srsr *srsr,
|
||||
spdk_nvmf_fc_caller_cb cb, void *cb_args);
|
||||
|
||||
uint32_t spdk_nvmf_fc_get_num_nport_ctrlrs_in_subsystem(uint8_t port_hdl, uint16_t nport_hdl,
|
||||
struct spdk_nvmf_subsystem *subsys);
|
||||
|
||||
bool spdk_nvmf_fc_is_spdk_ctrlr_on_nport(uint8_t port_hdl, uint16_t nport_hdl,
|
||||
struct spdk_nvmf_ctrlr *ctrlr);
|
||||
|
||||
int spdk_nvmf_fc_get_ctrlr_init_traddr(char *traddr, struct spdk_nvmf_ctrlr *ctrlr);
|
||||
|
||||
uint32_t spdk_nvmf_fc_get_hwqp_id(struct spdk_nvmf_request *req);
|
||||
|
||||
void spdk_nvmf_fc_req_abort(struct spdk_nvmf_fc_request *fc_req,
|
||||
bool send_abts, spdk_nvmf_fc_caller_cb cb,
|
||||
void *cb_args);
|
||||
|
||||
int spdk_nvmf_fc_add_port_listen(void *arg1, void *arg2);
|
||||
|
||||
int spdk_nvmf_fc_remove_port_listen(void *arg1, void *arg2);
|
||||
|
||||
void spdk_nvmf_fc_subsys_connect_cb(void *cb_ctx,
|
||||
struct spdk_nvmf_request *req);
|
||||
|
||||
void spdk_nvmf_fc_subsys_disconnect_cb(void *cb_ctx,
|
||||
struct spdk_nvmf_qpair *qpair);
|
||||
|
||||
uint32_t spdk_nvmf_fc_get_master_lcore(void);
|
||||
|
||||
struct spdk_thread *spdk_nvmf_fc_get_master_thread(void);
|
||||
|
||||
/*
|
||||
* These functions are used by low level FC driver
|
||||
* These functions are called by low level FC driver
|
||||
*/
|
||||
|
||||
static inline struct spdk_nvmf_fc_conn *
|
||||
@ -841,31 +993,26 @@ enum spdk_nvmf_fc_poller_api_ret spdk_nvmf_fc_poller_api_func(
|
||||
enum spdk_nvmf_fc_poller_api api,
|
||||
void *api_args);
|
||||
|
||||
int spdk_nvmf_fc_process_frame(struct spdk_nvmf_fc_hwqp *hwqp, uint32_t buff_idx,
|
||||
struct spdk_nvmf_fc_frame_hdr *frame,
|
||||
struct spdk_nvmf_fc_buffer_desc *buffer, uint32_t plen);
|
||||
int spdk_nvmf_fc_hwqp_process_frame(struct spdk_nvmf_fc_hwqp *hwqp, uint32_t buff_idx,
|
||||
struct spdk_nvmf_fc_frame_hdr *frame,
|
||||
struct spdk_nvmf_fc_buffer_desc *buffer, uint32_t plen);
|
||||
|
||||
void spdk_nvmf_fc_process_pending_req(struct spdk_nvmf_fc_hwqp *hwqp);
|
||||
void spdk_nvmf_fc_hwqp_process_pending_reqs(struct spdk_nvmf_fc_hwqp *hwqp);
|
||||
|
||||
void spdk_nvmf_fc_process_pending_ls_rqst(struct spdk_nvmf_fc_hwqp *hwqp);
|
||||
void spdk_nvmf_fc_hwqp_process_pending_ls_rqsts(struct spdk_nvmf_fc_hwqp *hwqp);
|
||||
|
||||
void spdk_nvmf_fc_req_set_state(struct spdk_nvmf_fc_request *fc_req,
|
||||
enum spdk_nvmf_fc_request_state state);
|
||||
void spdk_nvmf_fc_request_set_state(struct spdk_nvmf_fc_request *fc_req,
|
||||
enum spdk_nvmf_fc_request_state state);
|
||||
|
||||
void spdk_nvmf_fc_free_req(struct spdk_nvmf_fc_request *fc_req);
|
||||
char *spdk_nvmf_fc_request_get_state_str(int state);
|
||||
|
||||
void spdk_nvmf_fc_req_abort_complete(void *arg1);
|
||||
void spdk_nvmf_fc_request_free(struct spdk_nvmf_fc_request *fc_req);
|
||||
|
||||
void spdk_nvmf_fc_request_abort_complete(void *arg1);
|
||||
|
||||
bool spdk_nvmf_fc_send_ersp_required(struct spdk_nvmf_fc_request *fc_req,
|
||||
uint32_t rsp_cnt, uint32_t xfer_len);
|
||||
|
||||
struct spdk_nvmf_fc_xri *spdk_nvmf_fc_get_xri(struct spdk_nvmf_fc_hwqp *hwqp);
|
||||
|
||||
int spdk_nvmf_fc_put_xri(struct spdk_nvmf_fc_hwqp *hwqp,
|
||||
struct spdk_nvmf_fc_xri *xri);
|
||||
|
||||
void spdk_nvmf_fc_release_xri(struct spdk_nvmf_fc_hwqp *hwqp,
|
||||
struct spdk_nvmf_fc_xri *xri, bool xb, bool abts);
|
||||
|
||||
int spdk_nvmf_fc_handle_rsp(struct spdk_nvmf_fc_request *req);
|
||||
|
||||
#endif
|
||||
|
@ -47,6 +47,9 @@ static const struct spdk_nvmf_transport_ops *const g_transport_ops[] = {
|
||||
&spdk_nvmf_transport_rdma,
|
||||
#endif
|
||||
&spdk_nvmf_transport_tcp,
|
||||
#ifdef SPDK_CONFIG_FC
|
||||
&spdk_nvmf_transport_fc,
|
||||
#endif
|
||||
};
|
||||
|
||||
#define NUM_TRANSPORTS (SPDK_COUNTOF(g_transport_ops))
|
||||
@ -87,7 +90,7 @@ spdk_nvmf_transport_create(enum spdk_nvme_transport_type type,
|
||||
|
||||
ops = spdk_nvmf_get_transport_ops(type);
|
||||
if (!ops) {
|
||||
SPDK_ERRLOG("Transport type %s unavailable.\n",
|
||||
SPDK_ERRLOG("Transport type '%s' unavailable.\n",
|
||||
spdk_nvme_transport_id_trtype_str(type));
|
||||
return NULL;
|
||||
}
|
||||
|
@ -225,5 +225,6 @@ bool spdk_nvmf_transport_opts_init(enum spdk_nvme_transport_type type,
|
||||
|
||||
extern const struct spdk_nvmf_transport_ops spdk_nvmf_transport_rdma;
|
||||
extern const struct spdk_nvmf_transport_ops spdk_nvmf_transport_tcp;
|
||||
extern const struct spdk_nvmf_transport_ops spdk_nvmf_transport_fc;
|
||||
|
||||
#endif /* SPDK_NVMF_TRANSPORT_H */
|
||||
|
@ -48,4 +48,11 @@ ifeq ($(OS),Linux)
|
||||
SPDK_LIB_LIST += event_nbd nbd
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_FC),y)
|
||||
ifneq ($(strip $(CONFIG_FC_PATH)),)
|
||||
SYS_LIBS += -L$(CONFIG_FC_PATH)
|
||||
endif
|
||||
SYS_LIBS += -lufc
|
||||
endif
|
||||
|
||||
include $(SPDK_ROOT_DIR)/mk/spdk.app.mk
|
||||
|
@ -46,7 +46,7 @@ DEFINE_STUB(spdk_pci_ioat_get_driver, struct spdk_pci_driver *, (void), NULL)
|
||||
DEFINE_STUB(spdk_pci_virtio_get_driver, struct spdk_pci_driver *, (void), NULL)
|
||||
DEFINE_STUB(spdk_env_get_first_core, uint32_t, (void), 0);
|
||||
DEFINE_STUB(spdk_env_get_next_core, uint32_t, (uint32_t prev_core), 0);
|
||||
DEFINE_STUB(spdk_env_get_last_core, uint32_t, (void), 0);
|
||||
DEFINE_STUB(spdk_env_get_last_core, uint32_t, (void), 1);
|
||||
DEFINE_STUB(spdk_env_get_current_core, uint32_t, (void), 0);
|
||||
DEFINE_STUB(spdk_env_get_socket_id, uint32_t, (uint32_t core), 0);
|
||||
|
||||
|
@ -38,6 +38,8 @@ DIRS-y = tcp.c ctrlr.c subsystem.c ctrlr_discovery.c ctrlr_bdev.c
|
||||
|
||||
DIRS-$(CONFIG_RDMA) += rdma.c
|
||||
|
||||
DIRS-$(CONFIG_FC) += fc.c fc_ls.c
|
||||
|
||||
.PHONY: all clean $(DIRS-y)
|
||||
|
||||
all: $(DIRS-y)
|
||||
|
1
test/unit/lib/nvmf/fc.c/.gitignore
vendored
Normal file
1
test/unit/lib/nvmf/fc.c/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
fc_ut
|
58
test/unit/lib/nvmf/fc.c/Makefile
Normal file
58
test/unit/lib/nvmf/fc.c/Makefile
Normal file
@ -0,0 +1,58 @@
|
||||
#
|
||||
# BSD LICENSE
|
||||
#
|
||||
# Copyright (c) 2018 Broadcom. All Rights Reserved.
|
||||
# The term "Broadcom" refers to Broadcom Limited and/or its subsidiaries.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in
|
||||
# the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
# * Neither the name of Intel Corporation nor the names of its
|
||||
# contributors may be used to endorse or promote products derived
|
||||
# from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
|
||||
SPDK_ROOT_DIR := $(abspath $(CURDIR)/../../../../../)
|
||||
include $(SPDK_ROOT_DIR)/mk/config.mk
|
||||
|
||||
CFLAGS += -I$(SPDK_ROOT_DIR)/test/common/lib -I$(SPDK_ROOT_DIR)/lib \
|
||||
-I$(SPDK_ROOT_DIR)/lib/nvmf
|
||||
|
||||
ifneq ($(strip $(CONFIG_FC_PATH)),)
|
||||
CFLAGS += -I$(CONFIG_FC_PATH)
|
||||
endif
|
||||
|
||||
TEST_FILE = fc_ut.c
|
||||
|
||||
include $(SPDK_ROOT_DIR)/mk/spdk.unittest.mk
|
||||
|
||||
# Disable clang warning: taking address of packed member of class or structure may result in an unaligned pointer value [-Werror,-Waddress-of-packed-member]
|
||||
ifeq ($(CC),clang)
|
||||
CLANG_VERSION := $(shell $(CC) -v 2>&1 | \
|
||||
sed -n "s/.*version \([0-9]*\.[0-9]*\).*/\1/p")
|
||||
|
||||
CLANG_MAJOR_VERSION := $(shell echo $(CLANG_VERSION) | cut -f1 -d.)
|
||||
|
||||
ifeq ($(shell test $(CLANG_MAJOR_VERSION) -ge 4 && echo 1), 1)
|
||||
CFLAGS += -Wno-address-of-packed-member
|
||||
endif
|
||||
endif
|
536
test/unit/lib/nvmf/fc.c/fc_ut.c
Normal file
536
test/unit/lib/nvmf/fc.c/fc_ut.c
Normal file
@ -0,0 +1,536 @@
|
||||
/*
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright (c) 2018-2019 Broadcom. All Rights Reserved.
|
||||
* The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of Intel Corporation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* NVMF FC Transport Unit Test */
|
||||
|
||||
#include "spdk/env.h"
|
||||
#include "spdk_cunit.h"
|
||||
#include "spdk/nvmf.h"
|
||||
#include "spdk_internal/event.h"
|
||||
#include "spdk/endian.h"
|
||||
#include "spdk/trace.h"
|
||||
#include "spdk_internal/log.h"
|
||||
|
||||
#include "ut_multithread.c"
|
||||
|
||||
#include "transport.h"
|
||||
#include "nvmf_internal.h"
|
||||
#include "nvmf_fc.h"
|
||||
|
||||
#include "json/json_util.c"
|
||||
#include "json/json_write.c"
|
||||
#include "nvmf/nvmf.c"
|
||||
#include "nvmf/transport.c"
|
||||
#include "nvmf/subsystem.c"
|
||||
#include "nvmf/fc.c"
|
||||
#include "nvmf/fc_ls.c"
|
||||
|
||||
/*
|
||||
* SPDK Stuff
|
||||
*/
|
||||
|
||||
#ifdef SPDK_CONFIG_RDMA
|
||||
const struct spdk_nvmf_transport_ops spdk_nvmf_transport_rdma = {
|
||||
.type = SPDK_NVME_TRANSPORT_RDMA,
|
||||
.opts_init = NULL,
|
||||
.create = NULL,
|
||||
.destroy = NULL,
|
||||
|
||||
.listen = NULL,
|
||||
.stop_listen = NULL,
|
||||
.accept = NULL,
|
||||
|
||||
.listener_discover = NULL,
|
||||
|
||||
.poll_group_create = NULL,
|
||||
.poll_group_destroy = NULL,
|
||||
.poll_group_add = NULL,
|
||||
.poll_group_poll = NULL,
|
||||
|
||||
.req_free = NULL,
|
||||
.req_complete = NULL,
|
||||
|
||||
.qpair_fini = NULL,
|
||||
.qpair_is_idle = NULL,
|
||||
.qpair_get_peer_trid = NULL,
|
||||
.qpair_get_local_trid = NULL,
|
||||
.qpair_get_listen_trid = NULL,
|
||||
};
|
||||
#endif
|
||||
|
||||
const struct spdk_nvmf_transport_ops spdk_nvmf_transport_tcp = {
|
||||
.type = SPDK_NVME_TRANSPORT_TCP,
|
||||
};
|
||||
|
||||
struct spdk_trace_histories *g_trace_histories;
|
||||
|
||||
DEFINE_STUB_V(_spdk_trace_record, (uint64_t tsc, uint16_t tpoint_id, uint16_t poller_id,
|
||||
uint32_t size, uint64_t object_id, uint64_t arg1));
|
||||
DEFINE_STUB(spdk_env_get_core_count, uint32_t, (void), 4);
|
||||
DEFINE_STUB(spdk_nvme_transport_id_compare, int,
|
||||
(const struct spdk_nvme_transport_id *trid1,
|
||||
const struct spdk_nvme_transport_id *trid2), 0);
|
||||
DEFINE_STUB_V(spdk_trace_register_object, (uint8_t type, char id_prefix));
|
||||
DEFINE_STUB_V(spdk_trace_register_description,
|
||||
(const char *name, uint16_t tpoint_id, uint8_t owner_type,
|
||||
uint8_t object_type, uint8_t new_object, uint8_t arg1_type,
|
||||
const char *arg1_name));
|
||||
DEFINE_STUB_V(spdk_trace_add_register_fn, (struct spdk_trace_register_fn *reg_fn));
|
||||
DEFINE_STUB(spdk_bdev_get_name, const char *, (const struct spdk_bdev *bdev), "fc_ut_test");
|
||||
DEFINE_STUB_V(spdk_nvmf_ctrlr_destruct, (struct spdk_nvmf_ctrlr *ctrlr));
|
||||
DEFINE_STUB_V(spdk_nvmf_qpair_free_aer, (struct spdk_nvmf_qpair *qpair));
|
||||
DEFINE_STUB(spdk_bdev_get_io_channel, struct spdk_io_channel *, (struct spdk_bdev_desc *desc),
|
||||
NULL);
|
||||
DEFINE_STUB_V(spdk_nvmf_request_exec, (struct spdk_nvmf_request *req));
|
||||
DEFINE_STUB_V(spdk_nvmf_ctrlr_ns_changed, (struct spdk_nvmf_ctrlr *ctrlr, uint32_t nsid));
|
||||
DEFINE_STUB(spdk_bdev_open, int, (struct spdk_bdev *bdev, bool write,
|
||||
spdk_bdev_remove_cb_t remove_cb,
|
||||
void *remove_ctx, struct spdk_bdev_desc **desc), 0);
|
||||
DEFINE_STUB_V(spdk_bdev_close, (struct spdk_bdev_desc *desc));
|
||||
DEFINE_STUB(spdk_bdev_module_claim_bdev, int,
|
||||
(struct spdk_bdev *bdev, struct spdk_bdev_desc *desc,
|
||||
struct spdk_bdev_module *module), 0);
|
||||
DEFINE_STUB_V(spdk_bdev_module_release_bdev, (struct spdk_bdev *bdev));
|
||||
DEFINE_STUB(spdk_bdev_get_block_size, uint32_t, (const struct spdk_bdev *bdev), 512);
|
||||
|
||||
const char *
|
||||
spdk_nvme_transport_id_trtype_str(enum spdk_nvme_transport_type trtype)
|
||||
{
|
||||
switch (trtype) {
|
||||
case SPDK_NVME_TRANSPORT_PCIE:
|
||||
return "PCIe";
|
||||
case SPDK_NVME_TRANSPORT_RDMA:
|
||||
return "RDMA";
|
||||
case SPDK_NVME_TRANSPORT_FC:
|
||||
return "FC";
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
const char *
|
||||
spdk_nvme_transport_id_adrfam_str(enum spdk_nvmf_adrfam adrfam)
|
||||
{
|
||||
switch (adrfam) {
|
||||
case SPDK_NVMF_ADRFAM_IPV4:
|
||||
return "IPv4";
|
||||
case SPDK_NVMF_ADRFAM_IPV6:
|
||||
return "IPv6";
|
||||
case SPDK_NVMF_ADRFAM_IB:
|
||||
return "IB";
|
||||
case SPDK_NVMF_ADRFAM_FC:
|
||||
return "FC";
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
const struct spdk_uuid *
|
||||
spdk_bdev_get_uuid(const struct spdk_bdev *bdev)
|
||||
{
|
||||
return &bdev->uuid;
|
||||
}
|
||||
|
||||
static bool g_lld_init_called = false;
|
||||
|
||||
int
|
||||
nvmf_fc_lld_init(void)
|
||||
{
|
||||
g_lld_init_called = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool g_lld_fini_called = false;
|
||||
|
||||
void
|
||||
nvmf_fc_lld_fini(void)
|
||||
{
|
||||
g_lld_fini_called = true;
|
||||
}
|
||||
|
||||
DEFINE_STUB_V(nvmf_fc_lld_start, (void));
|
||||
DEFINE_STUB(nvmf_fc_init_q, int, (struct spdk_nvmf_fc_hwqp *hwqp), 0);
|
||||
DEFINE_STUB_V(nvmf_fc_reinit_q, (void *queues_prev, void *queues_curr));
|
||||
DEFINE_STUB(nvmf_fc_init_rqpair_buffers, int, (struct spdk_nvmf_fc_hwqp *hwqp), 0);
|
||||
DEFINE_STUB(nvmf_fc_set_q_online_state, int, (struct spdk_nvmf_fc_hwqp *hwqp, bool online), 0);
|
||||
DEFINE_STUB(nvmf_fc_put_xchg, int, (struct spdk_nvmf_fc_hwqp *hwqp, struct spdk_nvmf_fc_xchg *xri),
|
||||
0);
|
||||
DEFINE_STUB(nvmf_fc_recv_data, int, (struct spdk_nvmf_fc_request *fc_req), 0);
|
||||
DEFINE_STUB(nvmf_fc_send_data, int, (struct spdk_nvmf_fc_request *fc_req), 0);
|
||||
DEFINE_STUB_V(nvmf_fc_rqpair_buffer_release, (struct spdk_nvmf_fc_hwqp *hwqp, uint16_t buff_idx));
|
||||
DEFINE_STUB(nvmf_fc_xmt_rsp, int, (struct spdk_nvmf_fc_request *fc_req, uint8_t *ersp_buf,
|
||||
uint32_t ersp_len), 0);
|
||||
DEFINE_STUB(nvmf_fc_xmt_ls_rsp, int, (struct spdk_nvmf_fc_nport *tgtport,
|
||||
struct spdk_nvmf_fc_ls_rqst *ls_rqst), 0);
|
||||
DEFINE_STUB(nvmf_fc_issue_abort, int, (struct spdk_nvmf_fc_hwqp *hwqp,
|
||||
struct spdk_nvmf_fc_xchg *xri,
|
||||
spdk_nvmf_fc_caller_cb cb, void *cb_args), 0);
|
||||
DEFINE_STUB(nvmf_fc_xmt_bls_rsp, int, (struct spdk_nvmf_fc_hwqp *hwqp,
|
||||
uint16_t ox_id, uint16_t rx_id,
|
||||
uint16_t rpi, bool rjt, uint8_t rjt_exp,
|
||||
spdk_nvmf_fc_caller_cb cb, void *cb_args), 0);
|
||||
DEFINE_STUB(nvmf_fc_alloc_srsr_bufs, struct spdk_nvmf_fc_srsr_bufs *, (size_t rqst_len,
|
||||
size_t rsp_len), NULL);
|
||||
DEFINE_STUB_V(nvmf_fc_free_srsr_bufs, (struct spdk_nvmf_fc_srsr_bufs *srsr_bufs));
|
||||
DEFINE_STUB(nvmf_fc_xmt_srsr_req, int, (struct spdk_nvmf_fc_hwqp *hwqp,
|
||||
struct spdk_nvmf_fc_srsr_bufs *xmt_srsr_bufs,
|
||||
spdk_nvmf_fc_caller_cb cb, void *cb_args), 0);
|
||||
DEFINE_STUB(nvmf_fc_q_sync_available, bool, (void), true);
|
||||
DEFINE_STUB(nvmf_fc_issue_q_sync, int, (struct spdk_nvmf_fc_hwqp *hwqp, uint64_t u_id,
|
||||
uint16_t skip_rq), 0);
|
||||
DEFINE_STUB(nvmf_fc_assign_conn_to_hwqp, bool, (struct spdk_nvmf_fc_hwqp *hwqp,
|
||||
uint64_t *conn_id, uint32_t sq_size), true);
|
||||
DEFINE_STUB(nvmf_fc_get_hwqp_from_conn_id, struct spdk_nvmf_fc_hwqp *,
|
||||
(struct spdk_nvmf_fc_hwqp *queues,
|
||||
uint32_t num_queues, uint64_t conn_id), NULL);
|
||||
DEFINE_STUB_V(nvmf_fc_release_conn, (struct spdk_nvmf_fc_hwqp *hwqp, uint64_t conn_id,
|
||||
uint32_t sq_size));
|
||||
DEFINE_STUB_V(nvmf_fc_dump_all_queues, (struct spdk_nvmf_fc_hwqp *ls_queue,
|
||||
struct spdk_nvmf_fc_hwqp *io_queues,
|
||||
uint32_t num_io_queues,
|
||||
struct spdk_nvmf_fc_queue_dump_info *dump_info));
|
||||
DEFINE_STUB_V(nvmf_fc_get_xri_info, (struct spdk_nvmf_fc_hwqp *hwqp,
|
||||
struct spdk_nvmf_fc_xchg_info *info));
|
||||
DEFINE_STUB(nvmf_fc_get_rsvd_thread, struct spdk_thread *, (void), NULL);
|
||||
|
||||
uint32_t
|
||||
nvmf_fc_process_queue(struct spdk_nvmf_fc_hwqp *hwqp)
|
||||
{
|
||||
hwqp->lcore_id++;
|
||||
return 0; /* always return 0 or else it will poll forever */
|
||||
}
|
||||
|
||||
struct spdk_nvmf_fc_xchg *
|
||||
nvmf_fc_get_xri(struct spdk_nvmf_fc_hwqp *hwqp)
|
||||
{
|
||||
static struct spdk_nvmf_fc_xchg xchg;
|
||||
|
||||
xchg.xchg_id = 1;
|
||||
return &xchg;
|
||||
}
|
||||
|
||||
#define MAX_FC_UT_POLL_THREADS 8
|
||||
static struct spdk_nvmf_poll_group *g_poll_groups[MAX_FC_UT_POLL_THREADS] = {0};
|
||||
#define MAX_FC_UT_HWQPS MAX_FC_UT_POLL_THREADS
|
||||
static struct spdk_nvmf_tgt *g_nvmf_tgt = NULL;
|
||||
static struct spdk_nvmf_transport *g_nvmf_tprt = NULL;
|
||||
uint8_t g_fc_port_handle = 0xff;
|
||||
struct spdk_nvmf_fc_hwqp lld_q[MAX_FC_UT_HWQPS];
|
||||
|
||||
static void
|
||||
_add_transport_done(void *arg, int status)
|
||||
{
|
||||
CU_ASSERT(status == 0);
|
||||
}
|
||||
|
||||
static void
|
||||
_add_transport_done_dup_err(void *arg, int status)
|
||||
{
|
||||
CU_ASSERT(status == -EEXIST);
|
||||
}
|
||||
|
||||
static void
|
||||
create_transport_test(void)
|
||||
{
|
||||
const struct spdk_nvmf_transport_ops *ops = NULL;
|
||||
struct spdk_nvmf_transport_opts opts = { 0 };
|
||||
|
||||
allocate_threads(8);
|
||||
set_thread(0);
|
||||
|
||||
g_nvmf_tgt = spdk_nvmf_tgt_create(2);
|
||||
SPDK_CU_ASSERT_FATAL(g_nvmf_tgt != NULL);
|
||||
|
||||
ops = spdk_nvmf_get_transport_ops((enum spdk_nvme_transport_type) SPDK_NVMF_TRTYPE_FC);
|
||||
SPDK_CU_ASSERT_FATAL(ops != NULL);
|
||||
|
||||
ops->opts_init(&opts);
|
||||
|
||||
g_lld_init_called = false;
|
||||
g_nvmf_tprt = spdk_nvmf_transport_create((enum spdk_nvme_transport_type) SPDK_NVMF_TRTYPE_FC,
|
||||
&opts);
|
||||
SPDK_CU_ASSERT_FATAL(g_nvmf_tprt != NULL);
|
||||
|
||||
CU_ASSERT(g_lld_init_called == true);
|
||||
CU_ASSERT(opts.max_queue_depth == g_nvmf_tprt->opts.max_queue_depth);
|
||||
CU_ASSERT(opts.max_qpairs_per_ctrlr == g_nvmf_tprt->opts.max_qpairs_per_ctrlr);
|
||||
CU_ASSERT(opts.in_capsule_data_size == g_nvmf_tprt->opts.in_capsule_data_size);
|
||||
CU_ASSERT(opts.max_io_size == g_nvmf_tprt->opts.max_io_size);
|
||||
CU_ASSERT(opts.io_unit_size == g_nvmf_tprt->opts.io_unit_size);
|
||||
CU_ASSERT(opts.max_aq_depth == g_nvmf_tprt->opts.max_aq_depth);
|
||||
|
||||
set_thread(0);
|
||||
|
||||
spdk_nvmf_tgt_add_transport(g_nvmf_tgt, g_nvmf_tprt,
|
||||
_add_transport_done, 0);
|
||||
poll_thread(0);
|
||||
|
||||
/* Add transport again - should get error */
|
||||
spdk_nvmf_tgt_add_transport(g_nvmf_tgt, g_nvmf_tprt,
|
||||
_add_transport_done_dup_err, 0);
|
||||
poll_thread(0);
|
||||
|
||||
/* create transport with bad args/options */
|
||||
#ifndef SPDK_CONFIG_RDMA
|
||||
CU_ASSERT(spdk_nvmf_transport_create(SPDK_NVMF_TRTYPE_RDMA, &opts) == NULL);
|
||||
#endif
|
||||
CU_ASSERT(spdk_nvmf_transport_create(998, &opts) == NULL);
|
||||
opts.max_io_size = 1024 ^ 3;
|
||||
CU_ASSERT(spdk_nvmf_transport_create((enum spdk_nvme_transport_type) SPDK_NVMF_TRTYPE_FC,
|
||||
&opts) == NULL);
|
||||
opts.max_io_size = 999;
|
||||
opts.io_unit_size = 1024;
|
||||
CU_ASSERT(spdk_nvmf_transport_create((enum spdk_nvme_transport_type) SPDK_NVMF_TRTYPE_FC,
|
||||
&opts) == NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
port_init_cb(uint8_t port_handle, enum spdk_fc_event event_type, void *arg, int err)
|
||||
{
|
||||
CU_ASSERT(err == 0);
|
||||
CU_ASSERT(port_handle == 2);
|
||||
g_fc_port_handle = port_handle;
|
||||
}
|
||||
|
||||
static void
|
||||
create_fc_port_test(void)
|
||||
{
|
||||
struct spdk_nvmf_fc_hw_port_init_args init_args = { 0 };
|
||||
struct spdk_nvmf_fc_port *fc_port = NULL;
|
||||
int err;
|
||||
|
||||
SPDK_CU_ASSERT_FATAL(g_nvmf_tprt != NULL);
|
||||
|
||||
init_args.port_handle = 2;
|
||||
init_args.io_queue_cnt = spdk_min(MAX_FC_UT_HWQPS, spdk_env_get_core_count());
|
||||
init_args.ls_queue_size = 100;
|
||||
init_args.io_queue_size = 100;
|
||||
init_args.io_queues = (void *)lld_q;
|
||||
|
||||
set_thread(0);
|
||||
err = spdk_nvmf_fc_master_enqueue_event(SPDK_FC_HW_PORT_INIT, (void *)&init_args, port_init_cb);
|
||||
CU_ASSERT(err == 0);
|
||||
poll_thread(0);
|
||||
|
||||
fc_port = spdk_nvmf_fc_port_lookup(g_fc_port_handle);
|
||||
CU_ASSERT(fc_port != NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
online_fc_port_test(void)
|
||||
{
|
||||
struct spdk_nvmf_fc_port *fc_port;
|
||||
struct spdk_nvmf_fc_hw_port_online_args args;
|
||||
int err;
|
||||
|
||||
SPDK_CU_ASSERT_FATAL(g_nvmf_tprt != NULL);
|
||||
|
||||
fc_port = spdk_nvmf_fc_port_lookup(g_fc_port_handle);
|
||||
SPDK_CU_ASSERT_FATAL(fc_port != NULL);
|
||||
|
||||
set_thread(0);
|
||||
args.port_handle = g_fc_port_handle;
|
||||
err = spdk_nvmf_fc_master_enqueue_event(SPDK_FC_HW_PORT_ONLINE, (void *)&args, port_init_cb);
|
||||
CU_ASSERT(err == 0);
|
||||
poll_threads();
|
||||
set_thread(0);
|
||||
if (err == 0) {
|
||||
uint32_t i;
|
||||
for (i = 0; i < fc_port->num_io_queues; i++) {
|
||||
CU_ASSERT(fc_port->io_queues[i].fc_poll_group != 0);
|
||||
CU_ASSERT(fc_port->io_queues[i].fc_poll_group != 0);
|
||||
CU_ASSERT(fc_port->io_queues[i].fc_poll_group->hwqp_count != 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
create_poll_groups_test(void)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
SPDK_CU_ASSERT_FATAL(g_nvmf_tprt != NULL);
|
||||
|
||||
for (i = 0; i < MAX_FC_UT_POLL_THREADS; i++) {
|
||||
set_thread(i);
|
||||
g_poll_groups[i] = spdk_nvmf_poll_group_create(g_nvmf_tgt);
|
||||
poll_thread(i);
|
||||
CU_ASSERT(g_poll_groups[i] != NULL);
|
||||
}
|
||||
set_thread(0);
|
||||
}
|
||||
|
||||
static void
|
||||
poll_group_poll_test(void)
|
||||
{
|
||||
unsigned i;
|
||||
unsigned poll_cnt = 10;
|
||||
struct spdk_nvmf_fc_port *fc_port = NULL;
|
||||
|
||||
SPDK_CU_ASSERT_FATAL(g_nvmf_tprt != NULL);
|
||||
|
||||
set_thread(0);
|
||||
fc_port = spdk_nvmf_fc_port_lookup(g_fc_port_handle);
|
||||
SPDK_CU_ASSERT_FATAL(fc_port != NULL);
|
||||
|
||||
for (i = 0; i < fc_port->num_io_queues; i++) {
|
||||
fc_port->io_queues[i].lcore_id = 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < poll_cnt; i++) {
|
||||
/* this should cause spdk_nvmf_fc_poll_group_poll to be called() */
|
||||
poll_threads();
|
||||
}
|
||||
|
||||
/* check if hwqp's lcore_id has been updated */
|
||||
for (i = 0; i < fc_port->num_io_queues; i++) {
|
||||
CU_ASSERT(fc_port->io_queues[i].lcore_id == poll_cnt);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
remove_hwqps_from_poll_groups_test(void)
|
||||
{
|
||||
unsigned i;
|
||||
struct spdk_nvmf_fc_port *fc_port = NULL;
|
||||
|
||||
SPDK_CU_ASSERT_FATAL(g_nvmf_tprt != NULL);
|
||||
|
||||
fc_port = spdk_nvmf_fc_port_lookup(g_fc_port_handle);
|
||||
SPDK_CU_ASSERT_FATAL(fc_port != NULL);
|
||||
|
||||
for (i = 0; i < fc_port->num_io_queues; i++) {
|
||||
spdk_nvmf_fc_poll_group_remove_hwqp(&fc_port->io_queues[i]);
|
||||
poll_threads();
|
||||
CU_ASSERT(fc_port->io_queues[i].fc_poll_group == 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
destroy_transport_test(void)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
set_thread(0);
|
||||
SPDK_CU_ASSERT_FATAL(g_nvmf_tprt != NULL);
|
||||
|
||||
for (i = 0; i < MAX_FC_UT_POLL_THREADS; i++) {
|
||||
set_thread(i);
|
||||
spdk_nvmf_poll_group_destroy(g_poll_groups[i]);
|
||||
poll_thread(0);
|
||||
}
|
||||
|
||||
SPDK_CU_ASSERT_FATAL(g_nvmf_tgt != NULL);
|
||||
g_lld_fini_called = false;
|
||||
spdk_nvmf_tgt_destroy(g_nvmf_tgt, NULL, NULL);
|
||||
poll_threads();
|
||||
CU_ASSERT(g_lld_fini_called == true);
|
||||
}
|
||||
|
||||
static int
|
||||
nvmf_fc_tests_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
nvmf_fc_tests_fini(void)
|
||||
{
|
||||
free_threads();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
unsigned int num_failures = 0;
|
||||
CU_pSuite suite = NULL;
|
||||
|
||||
if (CU_initialize_registry() != CUE_SUCCESS) {
|
||||
return CU_get_error();
|
||||
}
|
||||
|
||||
suite = CU_add_suite("NVMf-FC", nvmf_fc_tests_init, nvmf_fc_tests_fini);
|
||||
if (suite == NULL) {
|
||||
CU_cleanup_registry();
|
||||
return CU_get_error();
|
||||
}
|
||||
|
||||
if (CU_add_test(suite, "Create Target & FC Transport",
|
||||
create_transport_test) == NULL) {
|
||||
CU_cleanup_registry();
|
||||
return CU_get_error();
|
||||
}
|
||||
|
||||
if (CU_add_test(suite, "Create Poll Groups",
|
||||
create_poll_groups_test) == NULL) {
|
||||
CU_cleanup_registry();
|
||||
return CU_get_error();
|
||||
}
|
||||
|
||||
if (CU_add_test(suite, "Create FC Port",
|
||||
create_fc_port_test) == NULL) {
|
||||
CU_cleanup_registry();
|
||||
return CU_get_error();
|
||||
}
|
||||
|
||||
|
||||
if (CU_add_test(suite, "Online FC Port",
|
||||
online_fc_port_test) == NULL) {
|
||||
CU_cleanup_registry();
|
||||
return CU_get_error();
|
||||
}
|
||||
|
||||
if (CU_add_test(suite, "PG poll", poll_group_poll_test) == NULL) {
|
||||
CU_cleanup_registry();
|
||||
return CU_get_error();
|
||||
}
|
||||
|
||||
if (CU_add_test(suite, "Remove HWQP's from PG's",
|
||||
remove_hwqps_from_poll_groups_test) == NULL) {
|
||||
CU_cleanup_registry();
|
||||
return CU_get_error();
|
||||
}
|
||||
|
||||
if (CU_add_test(suite, "Destroy Transport & Target",
|
||||
destroy_transport_test) == NULL) {
|
||||
CU_cleanup_registry();
|
||||
return CU_get_error();
|
||||
}
|
||||
|
||||
CU_basic_set_mode(CU_BRM_VERBOSE);
|
||||
CU_basic_run_tests();
|
||||
num_failures = CU_get_number_of_failures();
|
||||
CU_cleanup_registry();
|
||||
|
||||
return num_failures;
|
||||
}
|
1
test/unit/lib/nvmf/fc_ls.c/.gitignore
vendored
Normal file
1
test/unit/lib/nvmf/fc_ls.c/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
fc_ls_ut
|
45
test/unit/lib/nvmf/fc_ls.c/Makefile
Normal file
45
test/unit/lib/nvmf/fc_ls.c/Makefile
Normal file
@ -0,0 +1,45 @@
|
||||
#
|
||||
# BSD LICENSE
|
||||
#
|
||||
# Copyright (c) 2018 Broadcom. All Rights Reserved.
|
||||
# The term "Broadcom" refers to Broadcom Limited and/or its subsidiaries.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in
|
||||
# the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
# * Neither the name of Intel Corporation nor the names of its
|
||||
# contributors may be used to endorse or promote products derived
|
||||
# from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
|
||||
SPDK_ROOT_DIR := $(abspath $(CURDIR)/../../../../../)
|
||||
include $(SPDK_ROOT_DIR)/mk/config.mk
|
||||
|
||||
CFLAGS += -I$(SPDK_ROOT_DIR)/test/common/lib -I$(SPDK_ROOT_DIR)/lib/nvmf
|
||||
|
||||
ifneq ($(strip $(CONFIG_FC_PATH)),)
|
||||
CFLAGS += -I$(CONFIG_FC_PATH)
|
||||
endif
|
||||
|
||||
TEST_FILE = fc_ls_ut.c
|
||||
|
||||
include $(SPDK_ROOT_DIR)/mk/spdk.unittest.mk
|
1125
test/unit/lib/nvmf/fc_ls.c/fc_ls_ut.c
Normal file
1125
test/unit/lib/nvmf/fc_ls.c/fc_ls_ut.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -165,6 +165,14 @@ $valgrind $testdir/lib/ftl/ftl_md/ftl_md_ut
|
||||
$valgrind $testdir/lib/ftl/ftl_io.c/ftl_io_ut
|
||||
fi
|
||||
|
||||
if [ -e $testdir/lib/nvmf/fc.c/fc_ut ]; then
|
||||
$valgrind $testdir/lib/nvmf/fc.c/fc_ut
|
||||
fi
|
||||
|
||||
if [ -e $testdir/lib/nvmf/fc_ls.c/fc_ls_ut ]; then
|
||||
$valgrind $testdir/lib/nvmf/fc_ls.c/fc_ls_ut
|
||||
fi
|
||||
|
||||
# local unit test coverage
|
||||
if [ "$cov_avail" = "yes" ]; then
|
||||
$LCOV -q -d . -c -t "$(hostname)" -o $UT_COVERAGE/ut_cov_test.info
|
||||
|
Loading…
Reference in New Issue
Block a user