--- embedaddon/istgt/src/istgt_iscsi.c 2012/02/21 16:42:02 1.1.1.1 +++ embedaddon/istgt/src/istgt_iscsi.c 2012/10/09 09:13:23 1.1.1.2 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2011 Daisuke Aoyama . + * Copyright (C) 2008-2012 Daisuke Aoyama . * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -68,6 +68,11 @@ #include #endif +#if !defined(__GNUC__) +#undef __attribute__ +#define __attribute__(x) +#endif + /* according to RFC1982 */ #define SN32_CMPMAX (((uint32_t)1U) << (32 - 1)) #define SN32_LT(S1,S2) \ @@ -83,7 +88,7 @@ || ((uint32_t)(S1) > (uint32_t)(S2) \ && ((uint32_t)(S1) - (uint32_t)(S2) < SN32_CMPMAX)))) -#define POLLWAIT 3000 +#define POLLWAIT 5000 #define MAX_MCSREVWAIT (10 * 1000) #define ISCMDQ 8 @@ -157,7 +162,7 @@ istgt_iscsi_read(CONN_Ptr conn, void *buf, size_t nbyt } while (total < nbytes); if (total != (nbytes + pad_bytes)) { /* incomplete bytes */ - ISTGT_TRACELOG(ISTGT_TRACE_NET, "Read %d/%d+%d bytes\n", + ISTGT_TRACELOG(ISTGT_TRACE_NET, "Read %zd/%zd+%zd bytes\n", total, nbytes, pad_bytes); if (total > nbytes) { total = nbytes; @@ -167,11 +172,11 @@ istgt_iscsi_read(CONN_Ptr conn, void *buf, size_t nbyt if (pad_bytes != 0) { /* complete padding */ - ISTGT_TRACELOG(ISTGT_TRACE_NET, "Read %d bytes (padding %d)\n", + ISTGT_TRACELOG(ISTGT_TRACE_NET, "Read %zd bytes (padding %zd)\n", nbytes, pad_bytes); } else { /* just aligned */ - ISTGT_TRACELOG(ISTGT_TRACE_NET, "Read %d bytes (no padding)\n", + ISTGT_TRACELOG(ISTGT_TRACE_NET, "Read %zd bytes (no padding)\n", nbytes); } #else /* !ISTGT_USE_RECVBLOCK */ @@ -197,7 +202,7 @@ istgt_iscsi_read(CONN_Ptr conn, void *buf, size_t nbyt if (total != nbytes) { /* incomplete bytes */ - ISTGT_TRACELOG(ISTGT_TRACE_NET, "Read %d/%d bytes\n", + ISTGT_TRACELOG(ISTGT_TRACE_NET, "Read %zd/%zd bytes\n", total, nbytes); return total; } @@ -213,14 +218,14 @@ istgt_iscsi_read(CONN_Ptr conn, void *buf, size_t nbyt if (r < 0) { /* error */ ISTGT_TRACELOG(ISTGT_TRACE_NET, - "Read %d bytes (padding error) (errno=%d)\n", + "Read %zd bytes (padding error) (errno=%d)\n", nbytes, errno); return nbytes; } if (r == 0) { /* EOF */ ISTGT_TRACELOG(ISTGT_TRACE_NET, - "Read %d bytes (padding EOF)\n", + "Read %zd bytes (padding EOF)\n", nbytes); return nbytes; } @@ -230,18 +235,18 @@ istgt_iscsi_read(CONN_Ptr conn, void *buf, size_t nbyt if (total != pad_bytes) { /* incomplete padding */ ISTGT_TRACELOG(ISTGT_TRACE_NET, - "Read %d bytes (padding %d)\n", + "Read %zd bytes (padding %zd)\n", nbytes, total); return nbytes; } /* complete padding */ - ISTGT_TRACELOG(ISTGT_TRACE_NET, "Read %d bytes (padding %d)\n", + ISTGT_TRACELOG(ISTGT_TRACE_NET, "Read %zd bytes (padding %zd)\n", nbytes, pad_bytes); return nbytes; } /* just aligned */ - ISTGT_TRACELOG(ISTGT_TRACE_NET, "Read %d bytes (no padding)\n", + ISTGT_TRACELOG(ISTGT_TRACE_NET, "Read %zd bytes (no padding)\n", nbytes); #endif /* ISTGT_USE_RECVBLOCK */ return nbytes; @@ -273,7 +278,7 @@ istgt_iscsi_write(CONN_Ptr conn, const void *buf, size if (total != nbytes) { /* incomplete bytes */ - ISTGT_TRACELOG(ISTGT_TRACE_NET, "Write %d/%d bytes\n", + ISTGT_TRACELOG(ISTGT_TRACE_NET, "Write %zd/%zd bytes\n", total, nbytes); return total; } @@ -287,7 +292,7 @@ istgt_iscsi_write(CONN_Ptr conn, const void *buf, size if (r < 0) { /* error */ ISTGT_TRACELOG(ISTGT_TRACE_NET, - "Write %d bytes (padding error) (errno=%d)\n", + "Write %zd bytes (padding error) (errno=%d)\n", nbytes, errno); return nbytes; } @@ -297,19 +302,19 @@ istgt_iscsi_write(CONN_Ptr conn, const void *buf, size if (total != pad_bytes) { /* incomplete padding */ ISTGT_TRACELOG(ISTGT_TRACE_NET, - "Write %d bytes (padding %d)\n", + "Write %zd bytes (padding %zd)\n", nbytes, total); return nbytes; } /* complete padding */ ISTGT_TRACELOG(ISTGT_TRACE_NET, - "Write %d bytes (padding %d)\n", + "Write %zd bytes (padding %zd)\n", nbytes, pad_bytes); } else { /* just aligned */ ISTGT_TRACELOG(ISTGT_TRACE_NET, - "Write %d bytes (no padding)\n", + "Write %zd bytes (no padding)\n", nbytes); } #else /* !ISTGT_USE_SENDBLOCK */ @@ -327,7 +332,7 @@ istgt_iscsi_write(CONN_Ptr conn, const void *buf, size if (total != nbytes) { /* incomplete bytes */ - ISTGT_TRACELOG(ISTGT_TRACE_NET, "Write %d/%d bytes\n", + ISTGT_TRACELOG(ISTGT_TRACE_NET, "Write %zd/%zd bytes\n", total, nbytes); return r; } @@ -344,7 +349,7 @@ istgt_iscsi_write(CONN_Ptr conn, const void *buf, size if (r < 0) { /* error */ ISTGT_TRACELOG(ISTGT_TRACE_NET, - "Write %d bytes (padding error) (errno=%d)\n", + "Write %zd bytes (padding error) (errno=%d)\n", nbytes, errno); return nbytes; } @@ -354,19 +359,19 @@ istgt_iscsi_write(CONN_Ptr conn, const void *buf, size if (total != pad_bytes) { /* incomplete padding */ ISTGT_TRACELOG(ISTGT_TRACE_NET, - "Write %d bytes (padding %d)\n", + "Write %zd bytes (padding %zd)\n", nbytes, total); return nbytes; } /* complete padding */ ISTGT_TRACELOG(ISTGT_TRACE_NET, - "Write %d bytes (padding %d)\n", + "Write %zd bytes (padding %zd)\n", nbytes, pad_bytes); return nbytes; } /* just aligned */ - ISTGT_TRACELOG(ISTGT_TRACE_NET, "Write %d bytes (no padding)\n", + ISTGT_TRACELOG(ISTGT_TRACE_NET, "Write %zd bytes (no padding)\n", nbytes); #endif /* ISTGT_USE_SENDBLOCK */ return nbytes; @@ -623,7 +628,42 @@ istgt_iscsi_read_pdu(CONN_Ptr conn, ISCSI_PDU_Ptr pdu) } static int istgt_iscsi_write_pdu_internal(CONN_Ptr conn, ISCSI_PDU_Ptr pdu); +static int istgt_iscsi_write_pdu_queue(CONN_Ptr conn, ISCSI_PDU_Ptr pdu, int req_type, int I_bit); +static int istgt_update_pdu(CONN_Ptr conn, ISTGT_LU_CMD_Ptr lu_cmd) +{ + uint8_t *rsp; + uint32_t task_tag; + int opcode; + int I_bit; + + I_bit = lu_cmd->I_bit; + rsp = (uint8_t *) &lu_cmd->pdu->bhs; + opcode = BGET8W(&rsp[0], 5, 6); + task_tag = DGET32(&rsp[16]); + if ((opcode == ISCSI_OP_R2T) + || (opcode == ISCSI_OP_NOPIN && task_tag == 0xffffffffU)) { + SESS_MTX_LOCK(conn); + DSET32(&rsp[24], conn->StatSN); + DSET32(&rsp[28], conn->sess->ExpCmdSN); + DSET32(&rsp[32], conn->sess->MaxCmdSN); + SESS_MTX_UNLOCK(conn); + } else if ((opcode == ISCSI_OP_TASK_RSP) + || (opcode == ISCSI_OP_NOPIN && task_tag != 0xffffffffU)) { + SESS_MTX_LOCK(conn); + DSET32(&rsp[24], conn->StatSN); + conn->StatSN++; + if (I_bit == 0) { + conn->sess->ExpCmdSN++; + conn->sess->MaxCmdSN++; + } + DSET32(&rsp[28], conn->sess->ExpCmdSN); + DSET32(&rsp[32], conn->sess->MaxCmdSN); + SESS_MTX_UNLOCK(conn); + } + return 0; +} + static int istgt_iscsi_write_pdu(CONN_Ptr conn, ISCSI_PDU_Ptr pdu) { @@ -632,6 +672,32 @@ istgt_iscsi_write_pdu(CONN_Ptr conn, ISCSI_PDU_Ptr pdu if (conn->use_sender == 0) { rc = istgt_iscsi_write_pdu_internal(conn, pdu); } else { + rc = istgt_iscsi_write_pdu_queue(conn, pdu, ISTGT_LU_TASK_REQPDU, 0); + } + return rc; +} + +static int +istgt_iscsi_write_pdu_upd(CONN_Ptr conn, ISCSI_PDU_Ptr pdu, int I_bit) +{ + int rc; + + if (conn->use_sender == 0) { + rc = istgt_iscsi_write_pdu_internal(conn, pdu); + } else { + rc = istgt_iscsi_write_pdu_queue(conn, pdu, ISTGT_LU_TASK_REQUPDPDU, I_bit); + } + return rc; +} + +static int +istgt_iscsi_write_pdu_queue(CONN_Ptr conn, ISCSI_PDU_Ptr pdu, int req_type, int I_bit) +{ + int rc; + + if (conn->use_sender == 0) { + rc = istgt_iscsi_write_pdu_internal(conn, pdu); + } else { ISTGT_LU_TASK_Ptr lu_task; ISCSI_PDU_Ptr src_pdu, dst_pdu; uint8_t *cp; @@ -656,17 +722,21 @@ istgt_iscsi_write_pdu(CONN_Ptr conn, ISCSI_PDU_Ptr pdu alloc_len += ISCSI_ALIGN(data_len); lu_task = xmalloc(alloc_len); memset(lu_task, 0, alloc_len); - lu_task->lu_cmd.pdu = (ISCSI_PDU_Ptr) ((uint8_t *)lu_task + lu_task->lu_cmd.pdu = (ISCSI_PDU_Ptr) ((uintptr_t)lu_task + ISCSI_ALIGN(sizeof *lu_task)); - lu_task->lu_cmd.pdu->ahs = (ISCSI_AHS *) ((uint8_t *)lu_task->lu_cmd.pdu + lu_task->lu_cmd.pdu->ahs = (ISCSI_AHS *) ((uintptr_t)lu_task->lu_cmd.pdu + ISCSI_ALIGN(sizeof *lu_task->lu_cmd.pdu)); - lu_task->lu_cmd.pdu->data = (uint8_t *)lu_task->lu_cmd.pdu->ahs - + ISCSI_ALIGN(4 * total_ahs_len); + lu_task->lu_cmd.pdu->data = (uint8_t *) ((uintptr_t)lu_task->lu_cmd.pdu->ahs + + ISCSI_ALIGN(4 * total_ahs_len)); /* specify type and self conn */ - lu_task->type = ISTGT_LU_TASK_REQPDU; + //lu_task->type = ISTGT_LU_TASK_REQPDU; + lu_task->type = req_type; lu_task->conn = conn; + /* extra flags */ + lu_task->lu_cmd.I_bit = I_bit; + /* copy PDU structure */ src_pdu = pdu; dst_pdu = lu_task->lu_cmd.pdu; @@ -1346,7 +1416,7 @@ istgt_iscsi_negotiate_params(CONN_Ptr conn, ISCSI_PARA } static int -istgt_iscsi_append_text(CONN_Ptr conn, const char *key, const char *val, uint8_t *data, int alloc_len, int data_len) +istgt_iscsi_append_text(CONN_Ptr conn __attribute__((__unused__)), const char *key, const char *val, uint8_t *data, int alloc_len, int data_len) { int total; int len; @@ -1782,14 +1852,16 @@ istgt_iscsi_reject(CONN_Ptr conn, ISCSI_PDU_Ptr pdu, i DSET32(&rsp[16], 0xffffffffU); - DSET32(&rsp[24], conn->StatSN); - conn->StatSN++; if (conn->sess != NULL) { SESS_MTX_LOCK(conn); + DSET32(&rsp[24], conn->StatSN); + conn->StatSN++; DSET32(&rsp[28], conn->sess->ExpCmdSN); DSET32(&rsp[32], conn->sess->MaxCmdSN); SESS_MTX_UNLOCK(conn); } else { + DSET32(&rsp[24], conn->StatSN); + conn->StatSN++; DSET32(&rsp[28], 1); DSET32(&rsp[32], 1); } @@ -2298,8 +2370,8 @@ istgt_iscsi_op_login(CONN_Ptr conn, ISCSI_PDU_Ptr pdu) } /* initialize parameters */ - conn->StatSN = ExpStatSN; SESS_MTX_LOCK(conn); + conn->StatSN = ExpStatSN; conn->MaxOutstandingR2T = conn->sess->MaxOutstandingR2T; conn->sess->isid = isid; @@ -2574,14 +2646,16 @@ istgt_iscsi_op_login(CONN_Ptr conn, ISCSI_PDU_Ptr pdu) DSET16(&rsp[14], tsih); DSET32(&rsp[16], task_tag); - DSET32(&rsp[24], conn->StatSN); - conn->StatSN++; if (conn->sess != NULL) { SESS_MTX_LOCK(conn); + DSET32(&rsp[24], conn->StatSN); + conn->StatSN++; DSET32(&rsp[28], conn->sess->ExpCmdSN); DSET32(&rsp[32], conn->sess->MaxCmdSN); SESS_MTX_UNLOCK(conn); } else { + DSET32(&rsp[24], conn->StatSN); + conn->StatSN++; DSET32(&rsp[28], CmdSN); DSET32(&rsp[32], CmdSN); } @@ -2683,7 +2757,6 @@ istgt_iscsi_op_text(CONN_Ptr conn, ISCSI_PDU_Ptr pdu) ISTGT_ERRLOG("CmdSN(%u) error\n", CmdSN); return -1; } - SESS_MTX_UNLOCK(conn); if (SN32_GT(ExpStatSN, conn->StatSN)) { ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "StatSN(%u) advanced\n", ExpStatSN); @@ -2692,6 +2765,7 @@ istgt_iscsi_op_text(CONN_Ptr conn, ISCSI_PDU_Ptr pdu) if (ExpStatSN != conn->StatSN) { #if 0 ISTGT_ERRLOG("StatSN(%u) error\n", ExpStatSN); + SESS_MTX_UNLOCK(conn); return -1; #else /* StarPort have a bug */ @@ -2699,6 +2773,7 @@ istgt_iscsi_op_text(CONN_Ptr conn, ISCSI_PDU_Ptr pdu) conn->StatSN = ExpStatSN; #endif } + SESS_MTX_UNLOCK(conn); if (F_bit && C_bit) { ISTGT_ERRLOG("final and continue\n"); @@ -2768,9 +2843,9 @@ istgt_iscsi_op_text(CONN_Ptr conn, ISCSI_PDU_Ptr pdu) DSET32(&rsp[20], transfer_tag); } + SESS_MTX_LOCK(conn); DSET32(&rsp[24], conn->StatSN); conn->StatSN++; - SESS_MTX_LOCK(conn); if (I_bit == 0) { conn->sess->ExpCmdSN++; conn->sess->MaxCmdSN++; @@ -2850,6 +2925,9 @@ istgt_iscsi_op_logout(CONN_Ptr conn, ISCSI_PDU_Ptr pdu "CmdSN=%u, ExpStatSN=%u, StatSN=%u\n", CmdSN, ExpStatSN, conn->StatSN); } + if (conn->sess != NULL) { + SESS_MTX_LOCK(conn); + } if (SN32_GT(ExpStatSN, conn->StatSN)) { ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "StatSN(%u) advanced\n", ExpStatSN); @@ -2860,6 +2938,9 @@ istgt_iscsi_op_logout(CONN_Ptr conn, ISCSI_PDU_Ptr pdu ExpStatSN, conn->StatSN); /* ignore error */ } + if (conn->sess != NULL) { + SESS_MTX_UNLOCK(conn); + } response = 0; // connection or session closed successfully @@ -2875,10 +2956,10 @@ istgt_iscsi_op_logout(CONN_Ptr conn, ISCSI_PDU_Ptr pdu DSET32(&rsp[16], task_tag); - DSET32(&rsp[24], conn->StatSN); - conn->StatSN++; if (conn->sess != NULL) { SESS_MTX_LOCK(conn); + DSET32(&rsp[24], conn->StatSN); + conn->StatSN++; if (conn->sess->connections == 1) { conn->sess->ExpCmdSN++; conn->sess->MaxCmdSN++; @@ -2887,6 +2968,8 @@ istgt_iscsi_op_logout(CONN_Ptr conn, ISCSI_PDU_Ptr pdu DSET32(&rsp[32], conn->sess->MaxCmdSN); SESS_MTX_UNLOCK(conn); } else { + DSET32(&rsp[24], conn->StatSN); + conn->StatSN++; DSET32(&rsp[28], CmdSN); DSET32(&rsp[32], CmdSN); } @@ -3053,13 +3136,13 @@ istgt_iscsi_transfer_in_internal(CONN_Ptr conn, ISTGT_ DSET32(&rsp[16], task_tag); DSET32(&rsp[20], transfer_tag); + SESS_MTX_LOCK(conn); if (S_bit) { DSET32(&rsp[24], conn->StatSN); conn->StatSN++; } else { DSET32(&rsp[24], 0); // StatSN or Reserved } - SESS_MTX_LOCK(conn); if (F_bit && S_bit && lu_cmd->I_bit == 0) { conn->sess->MaxCmdSN++; } @@ -3104,12 +3187,12 @@ istgt_iscsi_op_scsi(CONN_Ptr conn, ISCSI_PDU_Ptr pdu) uint32_t transfer_len; uint32_t CmdSN; uint32_t ExpStatSN; + size_t bidi_residual_len; + size_t residual_len; + size_t data_len; + size_t alloc_len; int I_bit, F_bit, R_bit, W_bit, Attr_bit; int o_bit, u_bit, O_bit, U_bit; - int bidi_residual_len; - int residual_len; - int data_len; - int alloc_len; int rc; if (!conn->full_feature) { @@ -3219,7 +3302,6 @@ istgt_iscsi_op_scsi(CONN_Ptr conn, ISCSI_PDU_Ptr pdu) CmdSN, conn->sess->ExpCmdSN); return -1; } - SESS_MTX_UNLOCK(conn); if (SN32_GT(ExpStatSN, conn->StatSN)) { ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "StatSN(%u) advanced\n", ExpStatSN); @@ -3227,16 +3309,18 @@ istgt_iscsi_op_scsi(CONN_Ptr conn, ISCSI_PDU_Ptr pdu) } { uint32_t QCmdSN; - SESS_MTX_LOCK(conn); + //SESS_MTX_LOCK(conn); QCmdSN = conn->sess->MaxCmdSN - conn->sess->ExpCmdSN + 1; - SESS_MTX_UNLOCK(conn); + //SESS_MTX_UNLOCK(conn); QCmdSN += conn->queue_depth; if (SN32_LT(ExpStatSN + QCmdSN, conn->StatSN)) { ISTGT_ERRLOG("StatSN(%u/%u) QCmdSN(%u) error\n", ExpStatSN, conn->StatSN, QCmdSN); + SESS_MTX_UNLOCK(conn); return -1; } } + SESS_MTX_UNLOCK(conn); lu_cmd.pdu = pdu; SESS_MTX_LOCK(conn); @@ -3336,13 +3420,13 @@ istgt_iscsi_op_scsi(CONN_Ptr conn, ISCSI_PDU_Ptr pdu) && lu_cmd.status == ISTGT_SCSI_STATUS_GOOD) { if (data_len < transfer_len) { /* underflow */ - ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "Underflow %u/%u\n", + ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "Underflow %zu/%u\n", data_len, transfer_len); residual_len = transfer_len - data_len; U_bit = 1; } else if (data_len > transfer_len) { /* overflow */ - ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "Overflow %u/%u\n", + ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "Overflow %zu/%u\n", data_len, transfer_len); residual_len = data_len - transfer_len; O_bit = 1; @@ -3371,9 +3455,9 @@ istgt_iscsi_op_scsi(CONN_Ptr conn, ISCSI_PDU_Ptr pdu) DSET32(&rsp[16], task_tag); DSET32(&rsp[20], 0); // SNACK Tag + SESS_MTX_LOCK(conn); DSET32(&rsp[24], conn->StatSN); conn->StatSN++; - SESS_MTX_LOCK(conn); if (I_bit == 0) { conn->sess->MaxCmdSN++; } @@ -3418,11 +3502,11 @@ istgt_iscsi_task_response(CONN_Ptr conn, ISTGT_LU_TASK uint32_t task_tag; uint32_t transfer_len; uint32_t CmdSN; + size_t residual_len; + size_t data_len; int I_bit; int o_bit, u_bit, O_bit, U_bit; int bidi_residual_len; - int residual_len; - int data_len; int rc; lu_cmd = &lu_task->lu_cmd; @@ -3460,13 +3544,13 @@ istgt_iscsi_task_response(CONN_Ptr conn, ISTGT_LU_TASK && lu_cmd->status == ISTGT_SCSI_STATUS_GOOD) { if (data_len < transfer_len) { /* underflow */ - ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "Underflow %u/%u\n", + ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "Underflow %zu/%u\n", data_len, transfer_len); residual_len = transfer_len - data_len; U_bit = 1; } else if (data_len > transfer_len) { /* overflow */ - ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "Overflow %u/%u\n", + ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "Overflow %zu/%u\n", data_len, transfer_len); residual_len = data_len - transfer_len; O_bit = 1; @@ -3495,9 +3579,9 @@ istgt_iscsi_task_response(CONN_Ptr conn, ISTGT_LU_TASK DSET32(&rsp[16], task_tag); DSET32(&rsp[20], 0); // SNACK Tag + SESS_MTX_LOCK(conn); DSET32(&rsp[24], conn->StatSN); conn->StatSN++; - SESS_MTX_LOCK(conn); if (I_bit == 0) { conn->sess->MaxCmdSN++; } @@ -3570,7 +3654,6 @@ istgt_iscsi_op_task(CONN_Ptr conn, ISCSI_PDU_Ptr pdu) conn->sess->ExpCmdSN); conn->sess->ExpCmdSN = CmdSN; } - SESS_MTX_UNLOCK(conn); if (SN32_GT(ExpStatSN, conn->StatSN)) { ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "StatSN(%u) advanced\n", ExpStatSN); @@ -3584,6 +3667,7 @@ istgt_iscsi_op_task(CONN_Ptr conn, ISCSI_PDU_Ptr pdu) conn->StatSN = ExpStatSN; } #endif + SESS_MTX_UNLOCK(conn); response = 0; // Function complete. switch (function) { @@ -3675,18 +3759,22 @@ istgt_iscsi_op_task(CONN_Ptr conn, ISCSI_PDU_Ptr pdu) DSET32(&rsp[16], task_tag); - DSET32(&rsp[24], conn->StatSN); - conn->StatSN++; - SESS_MTX_LOCK(conn); - if (I_bit == 0) { - conn->sess->ExpCmdSN++; - conn->sess->MaxCmdSN++; + if (conn->use_sender == 0) { + SESS_MTX_LOCK(conn); + DSET32(&rsp[24], conn->StatSN); + conn->StatSN++; + if (I_bit == 0) { + conn->sess->ExpCmdSN++; + conn->sess->MaxCmdSN++; + } + DSET32(&rsp[28], conn->sess->ExpCmdSN); + DSET32(&rsp[32], conn->sess->MaxCmdSN); + SESS_MTX_UNLOCK(conn); + } else { + // update by sender } - DSET32(&rsp[28], conn->sess->ExpCmdSN); - DSET32(&rsp[32], conn->sess->MaxCmdSN); - SESS_MTX_UNLOCK(conn); - rc = istgt_iscsi_write_pdu(conn, &rsp_pdu); + rc = istgt_iscsi_write_pdu_upd(conn, &rsp_pdu, I_bit); if (rc < 0) { ISTGT_ERRLOG("iscsi_write_pdu() failed\n"); return -1; @@ -3752,10 +3840,10 @@ istgt_iscsi_op_nopout(CONN_Ptr conn, ISCSI_PDU_Ptr pdu } } else if (CmdSN != conn->sess->ExpCmdSN) { SESS_MTX_UNLOCK(conn); - ISTGT_ERRLOG("CmdSN(%u) error\n", CmdSN); + ISTGT_ERRLOG("CmdSN(%u) error ExpCmdSN=%u\n", + CmdSN, conn->sess->ExpCmdSN); return -1; } - SESS_MTX_UNLOCK(conn); if (SN32_GT(ExpStatSN, conn->StatSN)) { ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "StatSN(%u) advanced\n", ExpStatSN); @@ -3763,16 +3851,18 @@ istgt_iscsi_op_nopout(CONN_Ptr conn, ISCSI_PDU_Ptr pdu } { uint32_t QCmdSN; - SESS_MTX_LOCK(conn); + //SESS_MTX_LOCK(conn); QCmdSN = conn->sess->MaxCmdSN - conn->sess->ExpCmdSN + 1; - SESS_MTX_UNLOCK(conn); + //SESS_MTX_UNLOCK(conn); QCmdSN += conn->queue_depth; if (SN32_LT(ExpStatSN + QCmdSN, conn->StatSN)) { ISTGT_ERRLOG("StatSN(%u/%u) QCmdSN(%u) error\n", ExpStatSN, conn->StatSN, QCmdSN); + SESS_MTX_UNLOCK(conn); return -1; } } + SESS_MTX_UNLOCK(conn); if (task_tag == 0xffffffffU) { if (I_bit == 1) { @@ -3812,18 +3902,22 @@ istgt_iscsi_op_nopout(CONN_Ptr conn, ISCSI_PDU_Ptr pdu DSET32(&rsp[16], task_tag); DSET32(&rsp[20], transfer_tag); - DSET32(&rsp[24], conn->StatSN); - conn->StatSN++; - SESS_MTX_LOCK(conn); - if (I_bit == 0) { - conn->sess->ExpCmdSN++; - conn->sess->MaxCmdSN++; + if (conn->use_sender == 0) { + SESS_MTX_LOCK(conn); + DSET32(&rsp[24], conn->StatSN); + conn->StatSN++; + if (I_bit == 0) { + conn->sess->ExpCmdSN++; + conn->sess->MaxCmdSN++; + } + DSET32(&rsp[28], conn->sess->ExpCmdSN); + DSET32(&rsp[32], conn->sess->MaxCmdSN); + SESS_MTX_UNLOCK(conn); + } else { + // update by sender } - DSET32(&rsp[28], conn->sess->ExpCmdSN); - DSET32(&rsp[32], conn->sess->MaxCmdSN); - SESS_MTX_UNLOCK(conn); - rc = istgt_iscsi_write_pdu(conn, &rsp_pdu); + rc = istgt_iscsi_write_pdu_upd(conn, &rsp_pdu, I_bit); if (rc < 0) { ISTGT_ERRLOG("iscsi_write_pdu() failed\n"); return -1; @@ -3890,10 +3984,10 @@ istgt_add_transfer_task(CONN_Ptr conn, ISTGT_LU_CMD_Pt ISTGT_R2T_TASK_Ptr r2t_task; uint32_t transfer_len; uint32_t transfer_tag; - int first_burst_len; - int max_burst_len; - int data_len; - int offset = 0; + size_t first_burst_len; + size_t max_burst_len; + size_t data_len; + size_t offset = 0; int len; int idx; int rc; @@ -4049,10 +4143,10 @@ istgt_iscsi_op_data(CONN_Ptr conn, ISCSI_PDU_Ptr pdu) uint32_t ExpDataSN; uint32_t DataSN; uint32_t buffer_offset; + size_t data_len; + size_t alloc_len; + size_t offset; int F_bit; - int data_len; - int alloc_len; - int offset; int rc; if (!conn->full_feature) { @@ -4103,7 +4197,7 @@ istgt_iscsi_op_data(CONN_Ptr conn, ISCSI_PDU_Ptr pdu) ExpDataSN = r2t_task->DataSN; ISTGT_TRACELOG(ISTGT_TRACE_ISCSI, - "StatSN=%u, ExpStatSN=%u, DataSN=%u, Offset=%u, Data=%d\n", + "StatSN=%u, ExpStatSN=%u, DataSN=%u, Offset=%u, Data=%zd\n", conn->StatSN, ExpStatSN, DataSN, buffer_offset, data_len); if (DataSN != ExpDataSN) { ISTGT_ERRLOG("DataSN(%u) error\n", DataSN); @@ -4158,18 +4252,22 @@ istgt_iscsi_send_r2t(CONN_Ptr conn, ISTGT_LU_CMD_Ptr l DSET32(&rsp[16], lu_cmd->task_tag); DSET32(&rsp[20], transfer_tag); - DSET32(&rsp[24], conn->StatSN); - SESS_MTX_LOCK(conn); - DSET32(&rsp[28], conn->sess->ExpCmdSN); - DSET32(&rsp[32], conn->sess->MaxCmdSN); - SESS_MTX_UNLOCK(conn); + if (conn->use_sender == 0) { + SESS_MTX_LOCK(conn); + DSET32(&rsp[24], conn->StatSN); + DSET32(&rsp[28], conn->sess->ExpCmdSN); + DSET32(&rsp[32], conn->sess->MaxCmdSN); + SESS_MTX_UNLOCK(conn); + } else { + // update by sender + } DSET32(&rsp[36], *R2TSN); *R2TSN += 1; DSET32(&rsp[40], (uint32_t) offset); DSET32(&rsp[44], (uint32_t) len); - rc = istgt_iscsi_write_pdu(conn, &rsp_pdu); + rc = istgt_iscsi_write_pdu_upd(conn, &rsp_pdu, 0); if (rc < 0) { ISTGT_ERRLOG("iscsi_write_pdu() failed\n"); return -1; @@ -4179,7 +4277,7 @@ istgt_iscsi_send_r2t(CONN_Ptr conn, ISTGT_LU_CMD_Ptr l } int -istgt_iscsi_transfer_out(CONN_Ptr conn, ISTGT_LU_CMD_Ptr lu_cmd, uint8_t *data, int alloc_len, int transfer_len) +istgt_iscsi_transfer_out(CONN_Ptr conn, ISTGT_LU_CMD_Ptr lu_cmd, uint8_t *data, size_t alloc_len, size_t transfer_len) { ISTGT_R2T_TASK_Ptr r2t_task; ISCSI_PDU data_pdu; @@ -4195,13 +4293,13 @@ istgt_iscsi_transfer_out(CONN_Ptr conn, ISTGT_LU_CMD_P uint32_t DataSN; uint32_t buffer_offset; uint32_t R2TSN; + size_t data_len; + size_t segment_len; + size_t first_burst_len; + size_t max_burst_len; + size_t offset; int immediate, opcode; int F_bit; - int data_len; - int segment_len; - int first_burst_len; - int max_burst_len; - int offset; int len; int r2t_flag; int r2t_offset; @@ -4230,7 +4328,7 @@ istgt_iscsi_transfer_out(CONN_Ptr conn, ISTGT_LU_CMD_P } ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, - "Transfer=%d, First=%d, Max=%d, Segment=%d\n", + "Transfer=%zd, First=%zd, Max=%zd, Segment=%zd\n", transfer_len, data_len, max_burst_len, segment_len); r2t_task = istgt_get_transfer_task(conn, current_transfer_tag); @@ -4250,7 +4348,7 @@ istgt_iscsi_transfer_out(CONN_Ptr conn, ISTGT_LU_CMD_P istgt_free_transfer_task(r2t_task); ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, - "Using R2T(%d) offset=%d, DataSN=%d\n", + "Using R2T(%d) offset=%zd, DataSN=%d\n", conn->pending_r2t, offset, ExpDataSN); rc = istgt_queue_count(&conn->pending_pdus); @@ -4302,7 +4400,7 @@ istgt_iscsi_transfer_out(CONN_Ptr conn, ISTGT_LU_CMD_P data_pdu.copy_pdu = 0; do { ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, - "Transfer=%d, Offset=%d, Len=%d\n", + "Transfer=%zd, Offset=%zd, Len=%d\n", transfer_len, offset, len); /* send R2T if required */ if (r2t_flag == 0 @@ -4330,7 +4428,7 @@ istgt_iscsi_transfer_out(CONN_Ptr conn, ISTGT_LU_CMD_P r2t_sent = 1; ExpDataSN = 0; ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, - "R2T, Transfer=%d, Offset=%d, Len=%d\n", + "R2T, Transfer=%zd, Offset=%zd, Len=%d\n", transfer_len, offset, len); } else { r2t_sent = 0; @@ -4434,7 +4532,7 @@ istgt_iscsi_transfer_out(CONN_Ptr conn, ISTGT_LU_CMD_P ISTGT_TRACELOG(ISTGT_TRACE_ISCSI, "StatSN=%u, " - "ExpStatSN=%u, DataSN=%u, Offset=%u, Data=%d\n", + "ExpStatSN=%u, DataSN=%u, Offset=%u, Data=%zd\n", conn->StatSN, ExpStatSN, DataSN, buffer_offset, data_len); if (DataSN != ExpDataSN) { @@ -4488,7 +4586,7 @@ istgt_iscsi_transfer_out(CONN_Ptr conn, ISTGT_LU_CMD_P ExpDataSN++; if (r2t_flag == 0 && (offset > first_burst_len)) { - ISTGT_ERRLOG("data_len(%d) > first_burst_length(%d)", + ISTGT_ERRLOG("data_len(%zd) > first_burst_length(%zd)", offset, first_burst_len); goto error_return; } @@ -4534,7 +4632,7 @@ istgt_iscsi_transfer_out(CONN_Ptr conn, ISTGT_LU_CMD_P } r2t_return: - ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "Transfered=%d, Offset=%d\n", + ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "Transfered=%zd, Offset=%zd\n", transfer_len, offset); return 0; @@ -4586,13 +4684,17 @@ istgt_iscsi_send_nopin(CONN_Ptr conn) DSET32(&rsp[16], task_tag); DSET32(&rsp[20], transfer_tag); - DSET32(&rsp[24], conn->StatSN); - SESS_MTX_LOCK(conn); - DSET32(&rsp[28], conn->sess->ExpCmdSN); - DSET32(&rsp[32], conn->sess->MaxCmdSN); - SESS_MTX_UNLOCK(conn); + if (conn->use_sender == 0) { + SESS_MTX_LOCK(conn); + DSET32(&rsp[24], conn->StatSN); + DSET32(&rsp[28], conn->sess->ExpCmdSN); + DSET32(&rsp[32], conn->sess->MaxCmdSN); + SESS_MTX_UNLOCK(conn); + } else { + // update by sender + } - rc = istgt_iscsi_write_pdu(conn, &rsp_pdu); + rc = istgt_iscsi_write_pdu_upd(conn, &rsp_pdu, 0); if (rc < 0) { ISTGT_ERRLOG("iscsi_write_pdu() failed\n"); return -1; @@ -4711,7 +4813,7 @@ wait_all_task(CONN_Ptr conn) ISTGT_ERRLOG("kqueue() failed\n"); return; } - EV_SET(&kev, conn->task_pipe[0], EVFILT_READ, EV_ADD, 0, 0, NULL); + ISTGT_EV_SET(&kev, conn->task_pipe[0], EVFILT_READ, EV_ADD, 0, 0, NULL); rc = kevent(kq, &kev, 1, NULL, 0, NULL); if (rc == -1) { ISTGT_ERRLOG("kevent() failed\n"); @@ -4761,7 +4863,7 @@ wait_all_task(CONN_Ptr conn) #endif /* ISTGT_USE_KQUEUE */ #ifdef ISTGT_USE_KQUEUE - if (kev.ident == conn->task_pipe[0]) { + if (kev.ident == (uintptr_t)conn->task_pipe[0]) { if (kev.flags & (EV_EOF|EV_ERROR)) { break; } @@ -4963,8 +5065,13 @@ sender(void *arg) if (rc < 0) { lu_task->error = 1; ISTGT_ERRLOG( - "iscsi_task_response() failed on %s(%s)\n", + "iscsi_task_response() CmdSN=%u failed" + " on %s(%s)\n", lu_task->lu_cmd.CmdSN, conn->target_port, conn->initiator_port); + rc = write(conn->task_pipe[1], "E", 1); + if(rc < 0 || rc != 1) { + ISTGT_ERRLOG("write() failed\n"); + } break; } rc = istgt_lu_destroy_task(lu_task); @@ -4973,6 +5080,7 @@ sender(void *arg) break; } } else if (lu_task->type == ISTGT_LU_TASK_REQPDU) { + reqpdu: /* send PDU */ rc = istgt_iscsi_write_pdu_internal(lu_task->conn, lu_task->lu_cmd.pdu); @@ -4982,10 +5090,29 @@ sender(void *arg) "iscsi_write_pdu() failed on %s(%s)\n", lu_task->conn->target_port, lu_task->conn->initiator_port); + rc = write(conn->task_pipe[1], "E", 1); + if(rc < 0 || rc != 1) { + ISTGT_ERRLOG("write() failed\n"); + } break; } /* free allocated memory by caller */ xfree(lu_task); + } else if (lu_task->type == ISTGT_LU_TASK_REQUPDPDU) { + rc = istgt_update_pdu(lu_task->conn, &lu_task->lu_cmd); + if (rc < 0) { + lu_task->error = 1; + ISTGT_ERRLOG( + "update_pdu() failed on %s(%s)\n", + lu_task->conn->target_port, + lu_task->conn->initiator_port); + rc = write(conn->task_pipe[1], "E", 1); + if(rc < 0 || rc != 1) { + ISTGT_ERRLOG("write() failed\n"); + } + break; + } + goto reqpdu; } else { ISTGT_ERRLOG("Unknown task type %x\n", lu_task->type); rc = -1; @@ -5035,14 +5162,14 @@ worker(void *arg) return NULL; } conn->kq = kq; - EV_SET(&kev, conn->sock, EVFILT_READ, EV_ADD, 0, 0, NULL); + ISTGT_EV_SET(&kev, conn->sock, EVFILT_READ, EV_ADD, 0, 0, NULL); rc = kevent(kq, &kev, 1, NULL, 0, NULL); if (rc == -1) { ISTGT_ERRLOG("kevent() failed\n"); close(kq); return NULL; } - EV_SET(&kev, conn->task_pipe[0], EVFILT_READ, EV_ADD, 0, 0, NULL); + ISTGT_EV_SET(&kev, conn->task_pipe[0], EVFILT_READ, EV_ADD, 0, 0, NULL); rc = kevent(kq, &kev, 1, NULL, 0, NULL); if (rc == -1) { ISTGT_ERRLOG("kevent() failed\n"); @@ -5050,28 +5177,28 @@ worker(void *arg) return NULL; } - EV_SET(&kev, SIGINT, EVFILT_SIGNAL, EV_ADD, 0, 0, NULL); - rc = kevent(kq, &kev, 1, NULL, 0, NULL); - if (rc == -1) { - ISTGT_ERRLOG("kevent() failed\n"); - close(kq); - return NULL; + if (!conn->istgt->daemon) { + ISTGT_EV_SET(&kev, SIGINT, EVFILT_SIGNAL, EV_ADD, 0, 0, NULL); + rc = kevent(kq, &kev, 1, NULL, 0, NULL); + if (rc == -1) { + ISTGT_ERRLOG("kevent() failed\n"); + close(kq); + return NULL; + } + ISTGT_EV_SET(&kev, SIGTERM, EVFILT_SIGNAL, EV_ADD, 0, 0, NULL); + rc = kevent(kq, &kev, 1, NULL, 0, NULL); + if (rc == -1) { + ISTGT_ERRLOG("kevent() failed\n"); + close(kq); + return NULL; + } } - EV_SET(&kev, SIGTERM, EVFILT_SIGNAL, EV_ADD, 0, 0, NULL); - rc = kevent(kq, &kev, 1, NULL, 0, NULL); - if (rc == -1) { - ISTGT_ERRLOG("kevent() failed\n"); - close(kq); - return NULL; - } #else memset(&fds, 0, sizeof fds); fds[0].fd = conn->sock; fds[0].events = POLLIN; fds[1].fd = conn->task_pipe[0]; fds[1].events = POLLIN; - - nopin_timer = conn->nopininterval; #endif /* ISTGT_USE_KQUEUE */ conn->pdu.ahs = NULL; @@ -5108,6 +5235,9 @@ worker(void *arg) pthread_sigmask(SIG_UNBLOCK, &signew, &sigold); ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "loop start (%d)\n", conn->id); +#ifndef ISTGT_USE_KQUEUE + nopin_timer = conn->nopininterval; +#endif /* !ISTGT_USE_KQUEUE */ while (1) { /* check exit request */ if (conn->sess != NULL) { @@ -5187,6 +5317,7 @@ worker(void *arg) } if (rc == 0) { /* no fds */ + //ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "poll TIMEOUT\n"); if (nopin_timer > 0) { nopin_timer -= POLLWAIT; if (nopin_timer <= 0) { @@ -5205,7 +5336,7 @@ worker(void *arg) /* on socket */ #ifdef ISTGT_USE_KQUEUE - if (kev.ident == conn->sock) { + if (kev.ident == (uintptr_t)conn->sock) { if (kev.flags & (EV_EOF|EV_ERROR)) { ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "kevent EOF/ERROR\n"); @@ -5317,7 +5448,7 @@ worker(void *arg) /* execute on task queue */ #ifdef ISTGT_USE_KQUEUE - if (kev.ident == conn->task_pipe[0]) { + if (kev.ident == (uintptr_t)conn->task_pipe[0]) { if (kev.flags & (EV_EOF|EV_ERROR)) { ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "kevent EOF/ERROR\n"); @@ -5338,6 +5469,11 @@ worker(void *arg) ISTGT_ERRLOG("read() failed\n"); break; } + if (tmp[0] == 'E') { + ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "exit request (%d)\n", + conn->id); + break; + } /* DATA-IN/OUT */ MTX_LOCK(&conn->task_queue_mutex); @@ -5378,13 +5514,11 @@ worker(void *arg) lu_task = NULL; conn->exec_lu_task = NULL; } else { - MTX_LOCK(&lu_task->trans_mutex); //ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, // "Task Write Trans START\n"); rc = istgt_iscsi_task_transfer_out(conn, lu_task); if (rc < 0) { lu_task->error = 1; - MTX_UNLOCK(&lu_task->trans_mutex); ISTGT_ERRLOG("iscsi_task_transfer_out() failed on %s(%s)\n", conn->target_port, conn->initiator_port); @@ -5393,6 +5527,7 @@ worker(void *arg) //ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, // "Task Write Trans END\n"); + MTX_LOCK(&lu_task->trans_mutex); lu_task->req_transfer_out = 0; /* need response after execution */ @@ -5400,11 +5535,10 @@ worker(void *arg) if (conn->use_sender == 0) { conn->running_tasks++; } - MTX_UNLOCK(&lu_task->trans_mutex); rc = pthread_cond_broadcast(&lu_task->trans_cond); + MTX_UNLOCK(&lu_task->trans_mutex); if (rc != 0) { - //MTX_UNLOCK(&lu_task->trans_mutex); ISTGT_ERRLOG("cond_broadcast() failed\n"); break; } @@ -5476,8 +5610,11 @@ worker(void *arg) wait_all_task(conn); if (conn->use_sender) { + ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "stop sender thread (%d)\n", conn->id); /* stop sender thread */ + MTX_LOCK(&conn->result_queue_mutex); rc = pthread_cond_broadcast(&conn->result_queue_cond); + MTX_UNLOCK(&conn->result_queue_mutex); if (rc != 0) { ISTGT_ERRLOG("cond_broadcast() failed\n"); /* ignore errors */ @@ -5509,7 +5646,7 @@ worker(void *arg) } int -istgt_create_conn(ISTGT_Ptr istgt, PORTAL_Ptr portal, int sock, struct sockaddr *sa, socklen_t salen) +istgt_create_conn(ISTGT_Ptr istgt, PORTAL_Ptr portal, int sock, struct sockaddr *sa, socklen_t salen __attribute__((__unused__))) { char buf[MAX_TMPBUF]; CONN_Ptr conn; @@ -5659,12 +5796,12 @@ istgt_create_conn(ISTGT_Ptr istgt, PORTAL_Ptr portal, conn->task_pipe[1] = -1; goto error_return; } - rc = pthread_mutex_init(&conn->task_queue_mutex, NULL); + rc = pthread_mutex_init(&conn->task_queue_mutex, &istgt->mutex_attr); if (rc != 0) { ISTGT_ERRLOG("mutex_init() failed\n"); goto error_return; } - rc = pthread_mutex_init(&conn->result_queue_mutex, NULL); + rc = pthread_mutex_init(&conn->result_queue_mutex, &istgt->mutex_attr); if (rc != 0) { ISTGT_ERRLOG("mutex_init() failed\n"); goto error_return; @@ -5684,7 +5821,7 @@ istgt_create_conn(ISTGT_Ptr istgt, PORTAL_Ptr portal, ISTGT_ERRLOG("cond_init() failed\n"); goto error_return; } - rc = pthread_mutex_init(&conn->r2t_mutex, NULL); + rc = pthread_mutex_init(&conn->r2t_mutex, &istgt->mutex_attr); if (rc != 0) { ISTGT_ERRLOG("mutex_init() failed\n"); goto error_return; @@ -5761,6 +5898,7 @@ istgt_create_conn(ISTGT_Ptr istgt, PORTAL_Ptr portal, istgt_iscsi_param_free(conn->params); istgt_queue_destroy(&conn->pending_pdus); istgt_queue_destroy(&conn->task_queue); + istgt_queue_destroy(&conn->result_queue); xfree(conn->portal.label); xfree(conn->portal.host); xfree(conn->portal.port); @@ -6388,6 +6526,31 @@ istgt_get_active_conns(void) return num; } +int +istgt_stop_conns(void) +{ + CONN_Ptr conn; + char tmp[1]; + int rc; + int i; + + ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "istgt_stop_conns\n"); + tmp[0] = 'E'; + MTX_LOCK(&g_conns_mutex); + for (i = 0; i < g_nconns; i++) { + conn = g_conns[i]; + if (conn == NULL) + continue; + rc = write(conn->task_pipe[1], tmp, 1); + if(rc < 0 || rc != 1) { + ISTGT_ERRLOG("write() failed\n"); + /* ignore error */ + } + } + MTX_UNLOCK(&g_conns_mutex); + return 0; +} + CONN_Ptr istgt_find_conn(const char *initiator_port, const char *target_name, uint16_t tsih) { @@ -6463,7 +6626,7 @@ istgt_iscsi_init(ISTGT_Ptr istgt) } int -istgt_iscsi_shutdown(ISTGT_Ptr istgt) +istgt_iscsi_shutdown(ISTGT_Ptr istgt __attribute__((__unused__))) { CONN_Ptr conn; int retry = 10; @@ -6515,6 +6678,11 @@ istgt_iscsi_shutdown(ISTGT_Ptr istgt) if (rc != 0) { ISTGT_ERRLOG("mutex_destroy() failed\n"); return -1; + } + + if (num == 0) { + xfree(g_conns); + g_conns = NULL; } return 0;