nvmf: Add support of hotplug for nvmf virtual mode.

Change-Id: I941d119e6b74eadfccd7eb7675b2f7b46d2b5907
Signed-off-by: Cunyin Chang <cunyin.chang@intel.com>
This commit is contained in:
Cunyin Chang 2017-03-02 13:39:47 +08:00 committed by Daniel Verkamp
parent 39b386a5c5
commit e58e56c9c6
5 changed files with 50 additions and 4 deletions

View File

@ -131,7 +131,7 @@ struct spdk_nvmf_subsystem {
char subnqn[SPDK_NVMF_NQN_MAX_LEN]; char subnqn[SPDK_NVMF_NQN_MAX_LEN];
enum spdk_nvmf_subsystem_mode mode; enum spdk_nvmf_subsystem_mode mode;
enum spdk_nvmf_subtype subtype; enum spdk_nvmf_subtype subtype;
bool is_removed;
union { union {
struct { struct {
struct spdk_nvme_ctrlr *ctrlr; struct spdk_nvme_ctrlr *ctrlr;

View File

@ -363,12 +363,25 @@ spdk_nvmf_request_exec(struct spdk_nvmf_request *req)
assert(subsystem != NULL); assert(subsystem != NULL);
if (subsystem->subtype == SPDK_NVMF_SUBTYPE_DISCOVERY) { if (subsystem->subtype == SPDK_NVMF_SUBTYPE_DISCOVERY) {
status = nvmf_process_discovery_cmd(req); status = nvmf_process_discovery_cmd(req);
} else {
if (subsystem->is_removed) {
rsp->status.sc = SPDK_NVME_SC_ABORTED_BY_REQUEST;
status = SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE;
} else { } else {
status = subsystem->ops->process_admin_cmd(req); status = subsystem->ops->process_admin_cmd(req);
} }
}
} else {
struct spdk_nvmf_subsystem *subsystem;
subsystem = session->subsys;
if (subsystem->is_removed) {
rsp->status.sc = SPDK_NVME_SC_ABORTED_BY_REQUEST;
status = SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE;
} else { } else {
status = session->subsys->ops->process_io_cmd(req); status = session->subsys->ops->process_io_cmd(req);
} }
}
switch (status) { switch (status) {
case SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE: case SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE:

View File

@ -619,12 +619,32 @@ int
spdk_nvmf_session_poll(struct spdk_nvmf_session *session) spdk_nvmf_session_poll(struct spdk_nvmf_session *session)
{ {
struct spdk_nvmf_conn *conn, *tmp; struct spdk_nvmf_conn *conn, *tmp;
struct spdk_nvmf_subsystem *subsys = session->subsys;
if (subsys->is_removed && subsys->mode == NVMF_SUBSYSTEM_MODE_VIRTUAL) {
if (session->aer_req) {
struct spdk_nvmf_request *aer = session->aer_req;
aer->rsp->nvme_cpl.status.sct = SPDK_NVME_SCT_GENERIC;
aer->rsp->nvme_cpl.status.sc = SPDK_NVME_SC_ABORTED_SQ_DELETION;
aer->rsp->nvme_cpl.status.dnr = 0;
spdk_nvmf_request_complete(aer);
session->aer_req = NULL;
}
}
TAILQ_FOREACH_SAFE(conn, &session->connections, link, tmp) { TAILQ_FOREACH_SAFE(conn, &session->connections, link, tmp) {
if (conn->transport->conn_poll(conn) < 0) { if (conn->transport->conn_poll(conn) < 0) {
SPDK_ERRLOG("Transport poll failed for conn %p; closing connection\n", conn); SPDK_ERRLOG("Transport poll failed for conn %p; closing connection\n", conn);
spdk_nvmf_session_disconnect(conn); spdk_nvmf_session_disconnect(conn);
} }
if (subsys->subtype == SPDK_NVMF_SUBTYPE_NVME) {
if (subsys->is_removed && conn->transport->conn_is_idle(conn)) {
if (subsys->ops->detach) {
subsys->ops->detach(subsys);
}
}
}
} }
return 0; return 0;

View File

@ -463,6 +463,13 @@ spdk_nvmf_get_discovery_log_page(void *buffer, uint64_t offset, uint32_t length)
assert(copy_len + zero_len == length); assert(copy_len + zero_len == length);
} }
static void spdk_nvmf_ctrlr_hot_remove(void *remove_ctx)
{
struct spdk_nvmf_subsystem *subsystem = (struct spdk_nvmf_subsystem *)remove_ctx;
subsystem->is_removed = true;
}
int int
spdk_nvmf_subsystem_add_ns(struct spdk_nvmf_subsystem *subsystem, struct spdk_bdev *bdev) spdk_nvmf_subsystem_add_ns(struct spdk_nvmf_subsystem *subsystem, struct spdk_bdev *bdev)
{ {
@ -477,7 +484,7 @@ spdk_nvmf_subsystem_add_ns(struct spdk_nvmf_subsystem *subsystem, struct spdk_bd
return -1; return -1;
} }
if (!spdk_bdev_claim(bdev, NULL, NULL)) { if (!spdk_bdev_claim(bdev, spdk_nvmf_ctrlr_hot_remove, subsystem)) {
SPDK_ERRLOG("Subsystem %s: bdev %s is already claimed\n", SPDK_ERRLOG("Subsystem %s: bdev %s is already claimed\n",
subsystem->subnqn, bdev->name); subsystem->subnqn, bdev->name);
return -1; return -1;

View File

@ -67,6 +67,12 @@ test_foobar(void)
{ {
} }
int
spdk_nvmf_request_complete(struct spdk_nvmf_request *req)
{
return -1;
}
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
CU_pSuite suite = NULL; CU_pSuite suite = NULL;