VirtualBox

Changeset 74484 in vbox for trunk/src


Ignore:
Timestamp:
Sep 26, 2018 5:03:31 PM (6 years ago)
Author:
vboxsync
Message:

Network/IntNet: (bugref:9063) R0 trunk reconnect thread.

Location:
trunk/src/VBox
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Network/SrvIntNetR0.cpp

    r73097 r74484  
    358358    /** The SUPR0 object id. */
    359359    void                   *pvObj;
     360    /** The trunk reconnection system thread. The thread gets started at trunk
     361     * disconnection. It tries to reconnect the trunk to the bridged filter instance.
     362     * The thread erases this handle right before it terminates.
     363     */
     364    RTTHREAD                hTrunkReconnectThread;
     365    /** Trunk reconnection thread termination flag. */
     366    bool volatile           fTerminateReconnectThread;
    360367    /** Pointer to the temporary buffer that is used when snooping fragmented packets.
    361368     * This is allocated after this structure if we're sharing the MAC address with
     
    50535060
    50545061
     5062/* Forward declaration of trunk reconnection thread function. */
     5063static DECLCALLBACK(int) intnetR0TrunkReconnectThread(RTTHREAD hThread, void *pvUser);
     5064
    50555065/**
    50565066 * Creates a new network interface.
     
    53765386            pNetwork->MacTab.pTrunk = NULL;
    53775387            RTSpinlockRelease(pNetwork->hAddrSpinlock);
     5388
     5389            /*
     5390             * Create a system thread that will attempt to re-connect this trunk periodically
     5391             * hoping that the corresponding filter module reappears in the system. The thread
     5392             * will go away if it succeeds in re-connecting the trunk or if it is signalled.
     5393             */
     5394            int rc = RTThreadCreate(&pNetwork->hTrunkReconnectThread, intnetR0TrunkReconnectThread, pNetwork,
     5395                                    0, RTTHREADTYPE_INFREQUENT_POLLER, RTTHREADFLAGS_WAITABLE, "TRNKRECON");
     5396            AssertRC(rc);
    53785397
    53795398            intnetR0TrunkIfDestroy(pThis, pNetwork);
     
    58945913
    58955914
     5915/**
     5916 * Trunk reconnection thread function. It runs until signalled by another thread or by itself (upon
     5917 * successful trunk re-connection).
     5918 *
     5919 * Note that this function erases pNetwork->hTrunkReconnectThread right before it terminates!
     5920 */
     5921static DECLCALLBACK(int) intnetR0TrunkReconnectThread(RTTHREAD hThread, void *pvUser)
     5922{
     5923    RT_NOREF1(hThread);
     5924    PINTNETNETWORK pNetwork = (PINTNETNETWORK)pvUser;
     5925    PINTNET pIntNet = pNetwork->pIntNet;
     5926    Assert(pNetwork->pIntNet);
     5927
     5928    /*
     5929     * We attempt to reconnect the trunk every 5 seconds until somebody signals us.
     5930     */
     5931    while (!pNetwork->fTerminateReconnectThread && RTThreadUserWait(hThread, 5 * RT_MS_1SEC) == VERR_TIMEOUT)
     5932    {
     5933        /*
     5934         * Make sure nobody else is modifying networks.
     5935         * It is essential we give up on waiting for the big mutex much earlier than intnetR0NetworkDestruct
     5936         * gives up on waiting for us to terminate! This is why we wait for 1 second while network destruction
     5937         * code waits for 5 seconds. Otherwise the network may be already gone by the time we get the mutex.
     5938         */
     5939        if (RT_FAILURE(RTSemMutexRequestNoResume(pIntNet->hMtxCreateOpenDestroy, RT_MS_1SEC)))
     5940            continue;
     5941#if 0
     5942        /*
     5943         * This thread should be long gone by the time the network has been destroyed, but if we are
     5944         * really paranoid we should include the following code.
     5945         */
     5946        /*
     5947         * The network could have been destroyed while we were waiting on the big mutex, let us verify
     5948         * it is still valid by going over the list of existing networks.
     5949         */
     5950        PINTNETNETWORK pExistingNetwork = pIntNet->pNetworks;
     5951        for (; pExistingNetwork; pExistingNetwork = pExistingNetwork->pNext)
     5952            if (pExistingNetwork == pNetwork)
     5953                break;
     5954        /* We need the network to exist and to have at least one interface. */
     5955        if (pExistingNetwork && pNetwork->MacTab.cEntries)
     5956#else
     5957        /* We need the network to have at least one interface. */
     5958        if (pNetwork->MacTab.cEntries)
     5959#endif
     5960        {
     5961            PINTNETIF pAnyIf = pNetwork->MacTab.paEntries[0].pIf;
     5962            PSUPDRVSESSION pAnySession = pAnyIf ? pAnyIf->pSession : NULL;
     5963            if (pAnySession)
     5964            {
     5965                /* Attempt to re-connect trunk and if successful, terminate thread. */
     5966                if (RT_SUCCESS(intnetR0NetworkCreateTrunkIf(pNetwork, pAnySession)))
     5967                {
     5968                    /* The network has active interfaces, we need to activate the trunk. */
     5969                    if (pNetwork->cActiveIFs)
     5970                    {
     5971                        PINTNETTRUNKIF pTrunk = pNetwork->MacTab.pTrunk;
     5972                        /* The intnetR0NetworkCreateTrunkIf call resets fHostActive and fWireActive. */
     5973                        RTSpinlockAcquire(pNetwork->hAddrSpinlock);
     5974                        pNetwork->MacTab.fHostActive = RT_BOOL(pNetwork->fFlags & INTNET_OPEN_FLAGS_TRUNK_HOST_ENABLED);
     5975                        pNetwork->MacTab.fWireActive = RT_BOOL(pNetwork->fFlags & INTNET_OPEN_FLAGS_TRUNK_WIRE_ENABLED);
     5976                        RTSpinlockRelease(pNetwork->hAddrSpinlock);
     5977                        pTrunk->pIfPort->pfnSetState(pTrunk->pIfPort, INTNETTRUNKIFSTATE_ACTIVE);
     5978                    }
     5979                    pNetwork->fTerminateReconnectThread = true;
     5980                    RTThreadUserSignal(hThread); /* Signal ourselves, so we break the loop after releasing the mutex */
     5981                }
     5982            }
     5983        }
     5984        RTSemMutexRelease(pIntNet->hMtxCreateOpenDestroy);
     5985    }
     5986
     5987    /*
     5988     * Destroy our handle in INTNETNETWORK so everyone knows we are gone.
     5989     * Note that this is the only place where this handle gets wiped out.
     5990     */
     5991    pNetwork->hTrunkReconnectThread = NIL_RTTHREAD;
     5992
     5993    return VINF_SUCCESS;
     5994}
     5995
     5996
    58965997
    58975998/**
     
    59486049    if (pTrunk)
    59496050        intnetR0BusyWait(pNetwork, &pTrunk->cBusy);
     6051    else if (pNetwork->hTrunkReconnectThread != NIL_RTTHREAD)
     6052    {
     6053        /*
     6054         * There is no trunk and we have the trunk reconnection thread running.
     6055         * Signal the thread and wait for it to terminate.
     6056         */
     6057        pNetwork->fTerminateReconnectThread = true;
     6058        RTThreadUserSignal(pNetwork->hTrunkReconnectThread);
     6059        /*
     6060         * The tread cannot be re-connecting the trunk at the moment since we hold the big
     6061         * mutex, thus 5 second wait is definitely enough. Note that the wait time must
     6062         * exceed the time the reconnection thread waits on acquiring the big mutex, otherwise
     6063         * we will give up waiting for thread termination prematurely. Unfortunately it seems
     6064         * we have no way to terminate the thread if it failed to stop gracefully.
     6065         *
     6066         * Note that it is ok if the thread has already wiped out hTrunkReconnectThread by now,
     6067         * this means we no longer need to wait for it.
     6068         */
     6069        RTThreadWait(pNetwork->hTrunkReconnectThread, 5 * RT_MS_1SEC, NULL);
     6070    }
    59506071
    59516072    iIf = pNetwork->MacTab.cEntries;
     
    63506471    //pNetwork->pNext                       = NULL;
    63516472    //pNetwork->pIfs                        = NULL;
     6473    //pNetwork->fTerminateReconnectThread   = false;
     6474    pNetwork->hTrunkReconnectThread         = NIL_RTTHREAD;
    63526475    pNetwork->hAddrSpinlock                 = NIL_RTSPINLOCK;
    63536476    pNetwork->MacTab.cEntries               = 0;
     
    66446767    AssertReturnVoid(ASMAtomicCmpXchgU32(&pIntNet->u32Magic, ~INTNET_MAGIC, INTNET_MAGIC));
    66456768    Assert(pIntNet->pNetworks == NULL);
     6769    /*
     6770     * @todo Do we really need to be paranoid enough to go over the list of networks here,
     6771     * trying to terminate trunk re-connection threads here?
     6772     */
    66466773    if (pIntNet->hMtxCreateOpenDestroy != NIL_RTSEMMUTEX)
    66476774    {
  • trunk/src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetLwf-win.cpp

    r73852 r74484  
    26692669    }
    26702670    NdisReleaseSpinLock(&g_VBoxNetLwfGlobals.Lock);
    2671     vboxNetLwfLogErrorEvent(IO_ERR_INTERNAL_ERROR, STATUS_SUCCESS, 6);
     2671    // Internal network code will try to reconnect periodically, we should not spam in event log
     2672    //vboxNetLwfLogErrorEvent(IO_ERR_INTERNAL_ERROR, STATUS_SUCCESS, 6);
    26722673    LogFlow(("<==vboxNetFltOsInitInstance: return VERR_INTNET_FLT_IF_NOT_FOUND\n"));
    26732674    return VERR_INTNET_FLT_IF_NOT_FOUND;
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