Changeset 31616 in vbox
- Timestamp:
- Aug 12, 2010 6:15:04 PM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Storage/ISCSIHDDCore.cpp
r31608 r31616 805 805 pImage->aCmdsWaiting[idx] = NULL; 806 806 807 /* Get the tail. */ 808 pTail = pHead; 809 while (pTail->pNext) 810 pTail = pTail->pNext; 811 812 /* Concatenate. */ 813 pTail->pNext = pIScsiCmdHead; 814 pIScsiCmdHead = pHead; 807 if (pHead) 808 { 809 /* Get the tail. */ 810 pTail = pHead; 811 while (pTail->pNext) 812 pTail = pTail->pNext; 813 814 /* Concatenate. */ 815 pTail->pNext = pIScsiCmdHead; 816 pIScsiCmdHead = pHead; 817 } 815 818 } 816 819 … … 2239 2242 rc = pImage->pInterfaceNetCallbacks->pfnReadNB(pImage->Socket, pImage->pbRecvPDUBufCur, 2240 2243 pImage->cbRecvPDUResidual, &cbActuallyRead); 2244 if (RT_SUCCESS(rc) && cbActuallyRead == 0) 2245 rc = VERR_BROKEN_PIPE; 2246 2241 2247 if (RT_SUCCESS(rc)) 2242 2248 { … … 3133 3139 3134 3140 /** 3141 * Reattaches the to the target after an error aborting 3142 * pending commands and resending them. 3143 * 3144 * @param pImage iSCSI connection state. 3145 */ 3146 static void iscsiReattach(PISCSIIMAGE pImage) 3147 { 3148 int rc = VINF_SUCCESS; 3149 PISCSICMD pIScsiCmdHead = NULL; 3150 PISCSICMD pIScsiCmd = NULL; 3151 PISCSICMD pIScsiCmdCur = NULL; 3152 PISCSIPDUTX pIScsiPDUTx = NULL; 3153 3154 /* Close connection. */ 3155 iscsiTransportClose(pImage); 3156 pImage->state = ISCSISTATE_FREE; 3157 3158 /* Reset PDU we are receiving. */ 3159 iscsiRecvPDUReset(pImage); 3160 3161 /* 3162 * Abort all PDUs we are about to transmit, 3163 * the command need a new Itt if the relogin is successful. 3164 */ 3165 while (pImage->pIScsiPDUTxHead) 3166 { 3167 pIScsiPDUTx = pImage->pIScsiPDUTxHead; 3168 pImage->pIScsiPDUTxHead = pIScsiPDUTx->pNext; 3169 3170 pIScsiCmd = pIScsiPDUTx->pIScsiCmd; 3171 3172 if (pIScsiCmd) 3173 { 3174 /* Place on command list. */ 3175 pIScsiCmd->pNext = pIScsiCmdHead; 3176 pIScsiCmdHead = pIScsiCmd; 3177 } 3178 RTMemFree(pIScsiPDUTx); 3179 } 3180 3181 /* Clear the current PDU too. */ 3182 if (pImage->pIScsiPDUTxCur) 3183 { 3184 pIScsiPDUTx = pImage->pIScsiPDUTxCur; 3185 3186 pImage->pIScsiPDUTxCur = NULL; 3187 pIScsiCmd = pIScsiPDUTx->pIScsiCmd; 3188 3189 if (pIScsiCmd) 3190 { 3191 pIScsiCmd->pNext = pIScsiCmdHead; 3192 pIScsiCmdHead = pIScsiCmd; 3193 } 3194 RTMemFree(pIScsiPDUTx); 3195 } 3196 3197 /* 3198 * Get all commands which are waiting for a response 3199 * They need to be resend too after a successful reconnect. 3200 */ 3201 pIScsiCmd = iscsiCmdRemoveAll(pImage); 3202 3203 if (pIScsiCmd) 3204 { 3205 pIScsiCmdCur = pIScsiCmd; 3206 while (pIScsiCmdCur->pNext) 3207 pIScsiCmdCur = pIScsiCmdCur->pNext; 3208 3209 /* 3210 * Place them in front of the list because they are the oldest requests 3211 * and need to be processed first to minimize the risk to time out. 3212 */ 3213 pIScsiCmdCur->pNext = pIScsiCmdHead; 3214 pIScsiCmdHead = pIScsiCmd; 3215 } 3216 3217 /* Try to attach. */ 3218 rc = iscsiAttach(pImage); 3219 if (RT_SUCCESS(rc)) 3220 { 3221 /* Phew, we have a connection again. 3222 * Prepare new PDUs for the aborted commands. 3223 */ 3224 while (pIScsiCmdHead) 3225 { 3226 pIScsiCmd = pIScsiCmdHead; 3227 pIScsiCmdHead = pIScsiCmdHead->pNext; 3228 3229 rc = iscsiPDUTxPrepare(pImage, pIScsiCmd); 3230 AssertRC(rc); 3231 } 3232 } 3233 else 3234 { 3235 /* 3236 * Still no luck, complete commands with error so the caller 3237 * has a chance to inform the user and maybe resend the command. 3238 */ 3239 while (pIScsiCmdHead) 3240 { 3241 pIScsiCmd = pIScsiCmdHead; 3242 pIScsiCmdHead = pIScsiCmdHead->pNext; 3243 3244 iscsiCmdComplete(pImage, pIScsiCmd, VERR_BROKEN_PIPE); 3245 } 3246 } 3247 } 3248 3249 /** 3135 3250 * Internal. Main iSCSI I/O worker. 3136 3251 */ … … 3189 3304 LogFlow(("There is data on the socket\n")); 3190 3305 rc = iscsiRecvPDUAsync(pImage); 3306 if (rc == VERR_BROKEN_PIPE) 3307 iscsiReattach(pImage); 3191 3308 if (RT_FAILURE(rc)) 3192 3309 LogRel(("iSCSI: Handling incoming request failed %Rrc\n", rc)); … … 3201 3318 else if (fEvents & VD_INTERFACETCPNET_EVT_ERROR) 3202 3319 { 3203 PISCSICMD pIScsiCmdHead = NULL;3204 PISCSICMD pIScsiCmd = NULL;3205 PISCSICMD pIScsiCmdCur = NULL;3206 PISCSIPDUTX pIScsiPDUTx = NULL;3207 3320 LogFlow(("An error ocurred\n")); 3208 3209 /* Close connection. */ 3210 iscsiTransportClose(pImage); 3211 pImage->state = ISCSISTATE_FREE; 3212 3213 /* Reset PDU we are receiving. */ 3214 iscsiRecvPDUReset(pImage); 3215 3216 /* 3217 * Abort all PDUs we are about to transmit, 3218 * the command need a new Itt if the relogin is successful. 3219 */ 3220 while (pImage->pIScsiPDUTxHead) 3221 { 3222 pIScsiPDUTx = pImage->pIScsiPDUTxHead; 3223 pImage->pIScsiPDUTxHead = pIScsiPDUTx->pNext; 3224 3225 pIScsiCmd = pIScsiPDUTx->pIScsiCmd; 3226 3227 if (pIScsiCmd) 3228 { 3229 /* Place on command list. */ 3230 pIScsiCmd->pNext = pIScsiCmdHead; 3231 pIScsiCmdHead = pIScsiCmd; 3232 } 3233 RTMemFree(pIScsiPDUTx); 3234 } 3235 3236 /* Clear the current PDU too. */ 3237 if (pImage->pIScsiPDUTxCur) 3238 { 3239 pIScsiPDUTx = pImage->pIScsiPDUTxCur; 3240 3241 pImage->pIScsiPDUTxCur = NULL; 3242 pIScsiCmd = pIScsiPDUTx->pIScsiCmd; 3243 3244 if (pIScsiCmd) 3245 { 3246 pIScsiCmd->pNext = pIScsiCmdHead; 3247 pIScsiCmdHead = pIScsiCmd; 3248 } 3249 RTMemFree(pIScsiPDUTx); 3250 } 3251 3252 /* 3253 * Get all commands which are waiting for a response 3254 * They need to be resend too after a successful reconnect. 3255 */ 3256 pIScsiCmd = iscsiCmdRemoveAll(pImage); 3257 3258 pIScsiCmdCur = pIScsiCmd; 3259 while (pIScsiCmdCur->pNext) 3260 pIScsiCmdCur = pIScsiCmdCur->pNext; 3261 3262 /* 3263 * Place them in front of the list because they are the oldest requests 3264 * and need to be processed first to minimize the risk to time out. 3265 */ 3266 pIScsiCmdCur->pNext = pIScsiCmdHead; 3267 pIScsiCmdHead = pIScsiCmd; 3268 3269 /* Try to attach. */ 3270 rc = iscsiAttach(pImage); 3271 if (RT_SUCCESS(rc)) 3272 { 3273 /* Phew, we have a connection again. 3274 * Prepare new PDUs for the aborted commands. 3275 */ 3276 while (pIScsiCmdHead) 3277 { 3278 pIScsiCmd = pIScsiCmdHead; 3279 pIScsiCmdHead = pIScsiCmdHead->pNext; 3280 3281 rc = iscsiPDUTxPrepare(pImage, pIScsiCmd); 3282 AssertRC(rc); 3283 } 3284 } 3285 else 3286 { 3287 /* 3288 * Still no luck, complete commands with error so the caller 3289 * has a chance to inform the user and maybe resend the command. 3290 */ 3291 while (pIScsiCmdHead) 3292 { 3293 pIScsiCmd = pIScsiCmdHead; 3294 pIScsiCmdHead = pIScsiCmdHead->pNext; 3295 3296 iscsiCmdComplete(pImage, pIScsiCmd, VERR_BROKEN_PIPE); 3297 } 3298 } 3321 iscsiReattach(pImage); 3299 3322 } 3300 3323 else
Note:
See TracChangeset
for help on using the changeset viewer.