VirtualBox

Changeset 31616 in vbox


Ignore:
Timestamp:
Aug 12, 2010 6:15:04 PM (14 years ago)
Author:
vboxsync
Message:

iSCSI: Reattach when the target hangs up. Poll doesn't return with the error flag but indicates that there is data to read

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Storage/ISCSIHDDCore.cpp

    r31608 r31616  
    805805        pImage->aCmdsWaiting[idx] = NULL;
    806806
    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        }
    815818    }
    816819
     
    22392242    rc = pImage->pInterfaceNetCallbacks->pfnReadNB(pImage->Socket, pImage->pbRecvPDUBufCur,
    22402243                                                   pImage->cbRecvPDUResidual, &cbActuallyRead);
     2244    if (RT_SUCCESS(rc) && cbActuallyRead == 0)
     2245        rc = VERR_BROKEN_PIPE;
     2246
    22412247    if (RT_SUCCESS(rc))
    22422248    {
     
    31333139
    31343140/**
     3141 * Reattaches the to the target after an error aborting
     3142 * pending commands and resending them.
     3143 *
     3144 * @param    pImage    iSCSI connection state.
     3145 */
     3146static 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/**
    31353250 * Internal. Main iSCSI I/O worker.
    31363251 */
     
    31893304                LogFlow(("There is data on the socket\n"));
    31903305                rc = iscsiRecvPDUAsync(pImage);
     3306                if (rc == VERR_BROKEN_PIPE)
     3307                    iscsiReattach(pImage);
    31913308                if (RT_FAILURE(rc))
    31923309                    LogRel(("iSCSI: Handling incoming request failed %Rrc\n", rc));
     
    32013318            else if (fEvents & VD_INTERFACETCPNET_EVT_ERROR)
    32023319            {
    3203                 PISCSICMD pIScsiCmdHead = NULL;
    3204                 PISCSICMD pIScsiCmd = NULL;
    3205                 PISCSICMD pIScsiCmdCur = NULL;
    3206                 PISCSIPDUTX pIScsiPDUTx = NULL;
    32073320                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);
    32993322            }
    33003323            else
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette