diff --git a/lib/iscsi/conn.c b/lib/iscsi/conn.c index 97c1e5503..d5cd5d1e9 100644 --- a/lib/iscsi/conn.c +++ b/lib/iscsi/conn.c @@ -517,17 +517,11 @@ _spdk_iscsi_conn_check_shutdown(void *arg) return -1; } -void -spdk_iscsi_conn_destruct(struct spdk_iscsi_conn *conn) +static void +_spdk_iscsi_conn_destruct(struct spdk_iscsi_conn *conn) { int rc; - conn->state = ISCSI_CONN_STATE_EXITED; - - if (conn->sess != NULL && conn->pending_task_cnt > 0) { - spdk_iscsi_conn_cleanup_backend(conn); - } - spdk_clear_all_transfer_task(conn, NULL); spdk_iscsi_poll_group_remove_conn_sock(conn); spdk_sock_close(&conn->sock); @@ -544,6 +538,38 @@ spdk_iscsi_conn_destruct(struct spdk_iscsi_conn *conn) } } +static int +_spdk_iscsi_conn_check_pending_tasks(void *arg) +{ + struct spdk_iscsi_conn *conn = arg; + + if (conn->dev != NULL && spdk_scsi_dev_has_pending_tasks(conn->dev)) { + return -1; + } + + spdk_poller_unregister(&conn->shutdown_timer); + + _spdk_iscsi_conn_destruct(conn); + + return -1; +} + +void +spdk_iscsi_conn_destruct(struct spdk_iscsi_conn *conn) +{ + conn->state = ISCSI_CONN_STATE_EXITED; + + if (conn->sess != NULL && conn->pending_task_cnt > 0) { + spdk_iscsi_conn_cleanup_backend(conn); + } + + if (conn->dev != NULL && spdk_scsi_dev_has_pending_tasks(conn->dev)) { + conn->shutdown_timer = spdk_poller_register(_spdk_iscsi_conn_check_pending_tasks, conn, 1000); + } else { + _spdk_iscsi_conn_destruct(conn); + } +} + static int spdk_iscsi_get_active_conns(void) { diff --git a/test/unit/lib/iscsi/conn.c/conn_ut.c b/test/unit/lib/iscsi/conn.c/conn_ut.c index 5a9c852c8..88d23423b 100644 --- a/test/unit/lib/iscsi/conn.c/conn_ut.c +++ b/test/unit/lib/iscsi/conn.c/conn_ut.c @@ -154,6 +154,12 @@ spdk_scsi_dev_get_lun(struct spdk_scsi_dev *dev, int lun_id) return NULL; } +bool +spdk_scsi_dev_has_pending_tasks(const struct spdk_scsi_dev *dev) +{ + return true; +} + int spdk_scsi_lun_open(struct spdk_scsi_lun *lun, spdk_scsi_remove_cb_t hotremove_cb, void *hotremove_ctx, struct spdk_scsi_desc **desc)