Beispiel #1
0
DWORD
InitializeIndexingThread(
    VOID
    )
{
    DWORD   dwError = 0;

    dwError = VmDirSrvThrInit(
            &gVdirIndexGlobals.pThrInfo,
            gVdirIndexGlobals.mutex,
            gVdirIndexGlobals.cond,
            TRUE);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = VmDirCreateThread(
            &gVdirIndexGlobals.pThrInfo->tid,
            gVdirIndexGlobals.pThrInfo->bJoinThr,
            VmDirIndexingThreadFun,
            gVdirIndexGlobals.pThrInfo);
    BAIL_ON_VMDIR_ERROR(dwError);

cleanup:
    return dwError;

error:
    goto cleanup;
}
Beispiel #2
0
static
DWORD
VmDirPagedSearchCreateThread(
    PVDIR_PAGED_SEARCH_RECORD pSearchRecord
    )
{
    DWORD dwError = 0;
    PVDIR_THREAD_INFO pThrInfo = NULL;

    dwError = VmDirSrvThrInit(&pThrInfo, NULL, NULL, FALSE);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = VmDirCreateThread(
                &pThrInfo->tid,
                pThrInfo->bJoinThr,
                _VmDirPagedSearchWorkerThread,
                pSearchRecord);
    BAIL_ON_VMDIR_ERROR(dwError);

    pSearchRecord->pThreadInfo = pThrInfo;

cleanup:
    return dwError;

error:
    VmDirSrvThrFree(pThrInfo);
    goto cleanup;
}
Beispiel #3
0
DWORD
VmDirInitDCConnThread(
    PVMDIR_DC_CONNECTION pDCConn
    )
{
    DWORD dwError = 0;
    VMDIR_THREAD    threadId = {0};

    if (!pDCConn)
    {
        BAIL_WITH_VMDIR_ERROR(dwError, VMDIR_ERROR_INVALID_PARAMETER);
    }

    dwError = VmDirCreateThread(
        &threadId,
        FALSE,  // no thread join
        _VmDirDCConnThreadFun,
        pDCConn);
    BAIL_ON_VMDIR_ERROR(dwError);

cleanup:
    return dwError;

error:
    VMDIR_LOG_ERROR(VMDIR_LOG_MASK_ALL, "%s failed, error %d", __FUNCTION__, dwError);

    goto cleanup;
}
Beispiel #4
0
DWORD
VmDirInitRidSynchThr(
    PVDIR_THREAD_INFO* ppThrInfo
    )
{
    DWORD               dwError = 0;
    PVDIR_THREAD_INFO   pThrInfo = NULL;

    dwError = VmDirAllocateMemory(
                sizeof(*pThrInfo),
                (PVOID)&pThrInfo);
    BAIL_ON_VMDIR_ERROR(dwError);

    VmDirSrvThrInit(
                pThrInfo,
                NULL,
                NULL,
                TRUE);   // join by main thr

    dwError = VmDirCreateThread(
                &pThrInfo->tid,
                FALSE,
                _VmDirRidSyncThr,
                pThrInfo);
    BAIL_ON_VMDIR_ERROR(dwError);

    VmDirSrvThrAdd(pThrInfo);
    *ppThrInfo = pThrInfo;

cleanup:

    return dwError;

error:

    if (pThrInfo)
    {
        VmDirSrvThrFree(pThrInfo);
    }

    goto cleanup;
}
Beispiel #5
0
DWORD
InitializeDbChkpointThread(
    VOID)
{
    DWORD               dwError = 0;
    PVDIR_THREAD_INFO   pThrInfo = NULL;

    dwError = VmDirAllocateMemory(
            sizeof(*pThrInfo),
            (PVOID)&pThrInfo);
    BAIL_ON_VMDIR_ERROR(dwError);

    VmDirSrvThrInit(
            pThrInfo,
            NULL,
            NULL,
            TRUE);  // join by main thr

    dwError = VmDirCreateThread(
            &pThrInfo->tid,
            FALSE,
            VmDirBdbCheckpointThrFun,
            pThrInfo);
    BAIL_ON_VMDIR_ERROR(dwError);

    VmDirSrvThrAdd(pThrInfo);

cleanup:

    return (int)dwError;  //TODO, should not cast

error:

    if (pThrInfo)
    {
        VmDirSrvThrFree(pThrInfo);
    }

    goto cleanup;
}
Beispiel #6
0
DWORD
InitializeIndexingThread(
    void)
{
    DWORD       dwError = 0;
    PVDIR_THREAD_INFO   pThrInfo = NULL;

    dwError = VmDirAllocateMemory(
                  sizeof(*pThrInfo),
                  (PVOID)&pThrInfo);
    BAIL_ON_VMDIR_ERROR(dwError);

    VmDirSrvThrInit(
        pThrInfo,
        gVdirAttrIndexGlobals.mutex,       // alternative mutex
        gVdirAttrIndexGlobals.condition,   // alternative cond
        TRUE);                              // join by main thr

    dwError = VmDirCreateThread(
                  &pThrInfo->tid,
                  FALSE,
                  vdirIndexingThrFun,
                  pThrInfo);
    BAIL_ON_VMDIR_ERROR(dwError);

    VmDirSrvThrAdd(pThrInfo);

cleanup:

    return dwError;

error:

    if (pThrInfo)
    {
        VmDirSrvThrFree(pThrInfo);
    }

    goto cleanup;
}
Beispiel #7
0
static
DWORD
vmdirConnAccept(
    Sockbuf_IO*         pSockbuf_IO,
    DWORD               dwPort,
    BOOLEAN             bIsLdaps
    )
{
    ber_socket_t         newsockfd = -1;
    int                  retVal = LDAP_SUCCESS;
    ber_socket_t         ip4_fd = -1;
    ber_socket_t         ip6_fd = -1;
    ber_socket_t         max_fd = -1;
    VMDIR_THREAD         threadId;
    BOOLEAN              bInLock = FALSE;
    int                  iLocalLogMask = 0;
    PVDIR_CONNECTION_CTX pConnCtx = NULL;
    fd_set               event_fd_set;
    fd_set               poll_fd_set;
    struct timeval       timeout = {0};

    // Wait for ***1st*** replication cycle to be over.
    if (gVmdirServerGlobals.serverId == 0) // instance has not been initialized
    {
        VMDIR_LOG_WARNING( VMDIR_LOG_MASK_ALL, "Connection accept thread: Have NOT yet started listening on LDAP port (%u),"
                  " waiting for the 1st replication cycle to be over.", dwPort);

        VMDIR_LOCK_MUTEX(bInLock, gVmdirGlobals.replCycleDoneMutex);
        // wait till 1st replication cycle is over
        if (VmDirConditionWait( gVmdirGlobals.replCycleDoneCondition, gVmdirGlobals.replCycleDoneMutex ) != 0)
        {
            VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "Connection accept thread: VmDirConditionWait failed." );
            retVal = LDAP_OPERATIONS_ERROR;
            goto cleanup;
        }
        // also wake up the other (normal LDAP port/SSL LDAP port listner) LDAP connection accept thread,
        // waiting on 1st replication cycle to be over
        // BUGBUG Does not handle spurious wake up
        VmDirConditionSignal(gVmdirGlobals.replCycleDoneCondition);
        VMDIR_UNLOCK_MUTEX(bInLock, gVmdirGlobals.replCycleDoneMutex);

        if (VmDirdState() == VMDIRD_STATE_SHUTDOWN) // Asked to shutdown before we started accepting
        {
            goto cleanup;
        }

        VMDIR_LOG_INFO( VMDIR_LOG_MASK_ALL, "Connection accept thread: listening on LDAP port (%u).", dwPort);
    }

    iLocalLogMask = VmDirLogGetMask();
    ber_set_option(NULL, LBER_OPT_DEBUG_LEVEL, &iLocalLogMask);

    SetupLdapPort(dwPort, &ip4_fd, &ip6_fd);
    if (ip4_fd < 0 && ip6_fd < 0)
    {
        VmDirSleep(1000);
        goto cleanup;
    }

    FD_ZERO(&event_fd_set);
    if (ip4_fd >= 0)
    {
        FD_SET (ip4_fd, &event_fd_set);
        if (ip4_fd > max_fd)
        {
            max_fd = ip4_fd;
        }
    }

    if (ip6_fd >= 0)
    {
        FD_SET (ip6_fd, &event_fd_set);
        if (ip6_fd > max_fd)
        {
            max_fd = ip6_fd;
        }
    }

    retVal = VmDirSyncCounterIncrement(gVmdirGlobals.pPortListenSyncCounter);
    if (retVal != 0 )
    {
        VMDIR_LOG_ERROR(VMDIR_LOG_MASK_ALL, "%s: VmDirSyncCounterIncrement(gVmdirGlobals.pPortListenSyncCounter) returned error", __func__);
        BAIL_ON_VMDIR_ERROR(retVal);
    }

    while (TRUE)
    {
        if (VmDirdState() == VMDIRD_STATE_SHUTDOWN)
        {
            goto cleanup;
        }

        poll_fd_set = event_fd_set;
        timeout.tv_sec = 3;
        timeout.tv_usec = 0;
        retVal = select ((int)max_fd+1, &poll_fd_set, NULL, NULL, &timeout);
        if (retVal < 0 )
        {
#ifdef _WIN32
            errno = WSAGetLastError();
#endif
            VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "%s: select() (port %d) call failed: %d.", __func__, dwPort, errno);
            VmDirSleep( 1000 );
            continue;
        } else if (retVal == 0)
        {
            //VMDIR_LOG_INFO( LDAP_DEBUG_CONNS, "%s: select() timeout (port %d)", __func__, dwPort);
            continue;
        }

        if (ip4_fd >= 0 && FD_ISSET(ip4_fd, &poll_fd_set))
        {
            newsockfd = accept(ip4_fd, (struct sockaddr *) NULL, NULL);
        } else if (ip6_fd >= 0 && FD_ISSET(ip6_fd, &poll_fd_set))
        {
            newsockfd = accept(ip6_fd, (struct sockaddr *) NULL, NULL);
        } else
        {
            VMDIR_LOG_INFO( LDAP_DEBUG_CONNS, "%s: select() returned with no data (port %d), return: %d",
                            __func__, dwPort, retVal);
            continue;
        }

        if (newsockfd < 0)
        {
#ifdef _WIN32
            errno = WSAGetLastError();
#endif
            if (errno != EAGAIN && errno != EWOULDBLOCK )
            {
                VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "%s: accept() (port %d) failed with errno: %d.",
                                 __func__, dwPort, errno );
            }
            continue;
        }

        if ( _VmDirFlowCtrlThrEnter() == TRUE )
        {
            tcp_close(newsockfd);
            newsockfd = -1;
            VMDIR_LOG_WARNING( VMDIR_LOG_MASK_ALL, "Maxmimum number of concurrent LDAP threads reached. Blocking new connection" );

            continue;
        }

        retVal = VmDirAllocateMemory(
                sizeof(VDIR_CONNECTION_CTX),
                (PVOID*)&pConnCtx);
        BAIL_ON_VMDIR_ERROR(retVal);

        pConnCtx->sockFd  = newsockfd;
        newsockfd = -1;
        pConnCtx->pSockbuf_IO = pSockbuf_IO;

        retVal = VmDirCreateThread(&threadId, TRUE, ProcessAConnection, (PVOID)pConnCtx);
        if (retVal != 0)
        {
            VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "%s: VmDirCreateThread() (port) failed with errno: %d",
                             __func__, dwPort, errno );

            tcp_close(pConnCtx->sockFd);
            _VmDirFlowCtrlThrExit();
            VMDIR_SAFE_FREE_MEMORY(pConnCtx);
            continue;
        }
        else
        {
            pConnCtx = NULL; //thread take ownership on pConnCtx
            VmDirFreeVmDirThread(&threadId);
        }
    }

cleanup:

    VMDIR_UNLOCK_MUTEX(bInLock, gVmdirGlobals.replCycleDoneMutex);

    if (ip4_fd >= 0)
    {
        tcp_close(ip4_fd);
    }
    if (ip6_fd >= 0)
    {
        tcp_close(ip6_fd);
    }
    if (newsockfd >= 0)
    {
        tcp_close(newsockfd);
    }
#ifndef _WIN32
    raise(SIGTERM);
#endif

    VMDIR_LOG_INFO( VMDIR_LOG_MASK_ALL, "%s: Connection accept thread: stop (port %d)", __func__, dwPort);

    return retVal;

error:
    goto cleanup;
}
Beispiel #8
0
DWORD
VmDirInitConnAcceptThread(
    void
    )
{
    DWORD               dwError = 0;
    PDWORD              pdwLdapPorts = NULL;
    DWORD               dwLdapPorts = 0;
    PDWORD              pdwLdapsPorts = NULL;
    DWORD               dwLdapsPorts = 0;
    PVDIR_THREAD_INFO   pThrInfo = NULL;
    PDWORD              pdwPort = NULL;
    DWORD               i = 0;
    BOOLEAN             isIPV6AddressPresent = FALSE;
    BOOLEAN             isIPV4AddressPresent = FALSE;

    dwError = VmDirWhichAddressPresent(&isIPV4AddressPresent, &isIPV6AddressPresent);
    BAIL_ON_VMDIR_ERROR(dwError);
    if (isIPV4AddressPresent)
    {
       gVmdirServerGlobals.isIPV4AddressPresent = TRUE;
    }
    if (isIPV6AddressPresent)
    {
       gVmdirServerGlobals.isIPV6AddressPresent = TRUE;
    }

    VmDirGetLdapListenPorts(&pdwLdapPorts, &dwLdapPorts);
    VmDirGetLdapsListenPorts(&pdwLdapsPorts, &dwLdapsPorts);

    for (i = 0; i < dwLdapPorts; i++)
    {
        dwError = VmDirAllocateMemory(
                sizeof(*pThrInfo),
                (PVOID*)&pThrInfo);
        BAIL_ON_VMDIR_ERROR(dwError);

        dwError = VmDirAllocateMemory(
                sizeof(DWORD),
                (PVOID)&pdwPort);
        BAIL_ON_VMDIR_ERROR(dwError);

        *pdwPort = pdwLdapPorts[i];

        VmDirSrvThrInit(
                pThrInfo,
                gVmdirGlobals.replCycleDoneMutex,     // alternative mutex
                gVmdirGlobals.replCycleDoneCondition, // alternative cond
                FALSE);  // join by main thr

        dwError = VmDirCreateThread(
                &pThrInfo->tid,
                FALSE,
                vmdirConnAcceptThrFunc,
                (PVOID)pdwPort);  // New thread owns pdwPort
        BAIL_ON_VMDIR_ERROR(dwError);

        VmDirSrvThrAdd(pThrInfo);
        pThrInfo = NULL;
        pdwPort = NULL;
    }

    for (i = 0; gVmdirOpensslGlobals.bSSLInitialized && i < dwLdapsPorts; i++)
    {
        dwError = VmDirAllocateMemory(
                sizeof(*pThrInfo),
                (PVOID*)&pThrInfo);
        BAIL_ON_VMDIR_ERROR(dwError);

        dwError = VmDirAllocateMemory(
                sizeof(DWORD),
                (PVOID)&pdwPort);
        BAIL_ON_VMDIR_ERROR(dwError);

        *pdwPort = pdwLdapsPorts[i];

        VmDirSrvThrInit(
                pThrInfo,
                gVmdirGlobals.replCycleDoneMutex,     // alternative mutex
                gVmdirGlobals.replCycleDoneCondition, // alternative cond
                FALSE);  // join by main thr

        dwError = VmDirCreateThread(
                &pThrInfo->tid,
                FALSE,
                vmdirSSLConnAcceptThrFunc,
                (PVOID)pdwPort);
        BAIL_ON_VMDIR_ERROR(dwError);

        VmDirSrvThrAdd(pThrInfo);
        pThrInfo = NULL;
        pdwPort = NULL;
    }

cleanup:

    return dwError;

error:

    if (pThrInfo)
    {
        VmDirSrvThrFree(pThrInfo);
    }

    VMDIR_SAFE_FREE_MEMORY(pdwPort);

    goto cleanup;
}
Beispiel #9
0
/*
 * This thread waits on gVdirAttrIndexGlobals.condition and spawns worker thread
 * to perform indexing in the back ground.
 */
static
DWORD
vdirIndexingThrFun(
    PVOID   pArg
)
{
    DWORD   dwError = 0;
    BOOLEAN bInLock = FALSE;
    PVDIR_CFG_ATTR_INDEX_DESC*  ppIndexDesc = NULL;
    PVDIR_THREAD_INFO           pThrInfo = (PVDIR_THREAD_INFO)pArg;

    while (1)
    {
        DWORD   dwCnt = 0;
        DWORD   dwSize = 0;
        VMDIR_THREAD  tid = {0};
        PVDIR_ATTR_INDEX_INSTANCE pCache = NULL;

        memset(&tid, 0, sizeof(tid));

        // wait till new indices are created
        VMDIR_LOCK_MUTEX(bInLock, gVdirAttrIndexGlobals.mutex);

        dwError = VmDirConditionWait(
                      pThrInfo->conditionUsed,
                      pThrInfo->mutexUsed);
        BAIL_ON_VMDIR_ERROR(dwError);

        // get new cache we want to enable
        pCache = gVdirAttrIndexGlobals.pNewCache;

        VMDIR_UNLOCK_MUTEX(bInLock, gVdirAttrIndexGlobals.mutex);

        if (VmDirdState() == VMDIRD_STATE_SHUTDOWN)
        {
            break;
        }

        if (!pCache)
        {
            continue;
        }

        // get number of indices in building status
        for (dwCnt = 0, dwSize = 0; dwCnt < pCache->usNumIndex; dwCnt++)
        {
            if (pCache->pSortName[dwCnt].status == VDIR_CFG_ATTR_INDEX_BUILDING)
            {
                dwSize++;
            }
        }

        if (dwSize == 0)
        {
            continue;
        }

        dwError  = VmDirAllocateMemory(
                       sizeof(PVDIR_CFG_ATTR_INDEX_DESC) * (dwSize + 1),  // +1 for NULL ending
                       (PVOID)&ppIndexDesc);
        BAIL_ON_VMDIR_ERROR(dwError);

        // fill ppIndexDesc with building index
        // NOTE, ppIndexDesc does NOT own them; pCache does.
        for (dwCnt = 0, dwSize = 0; dwCnt < pCache->usNumIndex; dwCnt++)
        {
            if (pCache->pSortName[dwCnt].status == VDIR_CFG_ATTR_INDEX_BUILDING)
            {
                ppIndexDesc[dwSize] = &pCache->pSortName[dwCnt];
                dwSize++;
            }
        }

        // TODO, detach thr now, need to join to safely finish bdb io...
        dwError = VmDirCreateThread(
                      &tid,
                      TRUE,
                      vdirIndexingWorkerThrFun,
                      (PVOID)ppIndexDesc);
        BAIL_ON_VMDIR_ERROR(dwError);
        // worker takes over ppIndexDesc.
        ppIndexDesc = NULL;

        VmDirFreeVmDirThread(&tid);
    }

cleanup:

    VMDIR_UNLOCK_MUTEX(bInLock, gVdirAttrIndexGlobals.mutex);

    // TODO: should be dwError?
    return 0;

error:

    VMDIR_SAFE_FREE_MEMORY(ppIndexDesc);

    //TODO, should we stop vmdird?

    VmDirLog( LDAP_DEBUG_ANY, "VmdirIndexingThr: error stop" );

    goto cleanup;
}