Example #1
0
static
NTSTATUS
InitPool(
    VOID
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    PLW_THREAD_POOL pNewPool = NULL;

    if (!gSvcmState.pPool)
    {
        status = LwRtlCreateThreadPool(&pNewPool, NULL);
        GCOS(status);

        if (InterlockedCompareExchangePointer(
            OUT_PPVOID(&gSvcmState.pPool),
            pNewPool,
            NULL) != NULL)
        {
            LwRtlFreeThreadPool(&pNewPool);
        }
    }

cleanup:

    return status;
}
Example #2
0
VOID
ReleaseDelegatePool(
    PLW_THREAD_POOL* ppPool
    )
{
    BOOLEAN bFree = FALSE;

    if (*ppPool)
    {
        pthread_mutex_lock(&gpDelegateLock);
        
        assert(*ppPool == gpDelegatePool);
        
        if (--gpDelegatePoolRefCount == 0)
        {
            gpDelegatePool = NULL;
            bFree = TRUE;
        }
        
        pthread_mutex_unlock(&gpDelegateLock);
    }

    if (bFree)
    {
        LwRtlFreeThreadPool(ppPool);
    }
}
Example #3
0
VOID
LwRtlSvcmFreePool(
    VOID
    )
{
    LwRtlFreeThreadPool((PLW_THREAD_POOL*) &gSvcmState.pPool);
}
Example #4
0
VOID
SvcmDestructor(
    VOID
    )
{
    LwRtlFreeThreadPool((PLW_THREAD_POOL*) &gSvcmState.pPool);
}
Example #5
0
static
NTSTATUS
RdrShutdown(
    VOID
    )
{
    NTSTATUS status = STATUS_SUCCESS;

    /* We need to run down all cached tress/session/sockets sitting around.
     * Set the global shutdown flag, then cancel and wait for each task group
     * in turn.
     */
    RdrSetShutdown();

    if (gRdrRuntime.pTreeTimerGroup)
    {
        LwRtlCancelTaskGroup(gRdrRuntime.pTreeTimerGroup);
        LwRtlWaitTaskGroup(gRdrRuntime.pTreeTimerGroup);
    }

    if (gRdrRuntime.pSessionTimerGroup)
    {
        LwRtlCancelTaskGroup(gRdrRuntime.pSessionTimerGroup);
        LwRtlWaitTaskGroup(gRdrRuntime.pSessionTimerGroup);
    }

    if (gRdrRuntime.pSocketTimerGroup)
    {
        LwRtlCancelTaskGroup(gRdrRuntime.pSocketTimerGroup);
        LwRtlWaitTaskGroup(gRdrRuntime.pSocketTimerGroup);
    }

    /* All socket tasks should have been canceled by this point,
     * so wait for them to finish shutting down
     */
    if (gRdrRuntime.pSocketTaskGroup)
    {
        LwRtlWaitTaskGroup(gRdrRuntime.pSocketTaskGroup);
    }

    /* Now we can free everything */
    LwRtlFreeTaskGroup(&gRdrRuntime.pTreeTimerGroup);
    LwRtlFreeTaskGroup(&gRdrRuntime.pSessionTimerGroup);
    LwRtlFreeTaskGroup(&gRdrRuntime.pSocketTimerGroup);
    LwRtlFreeTaskGroup(&gRdrRuntime.pSocketTaskGroup);
    SMBHashSafeFree(&gRdrRuntime.pSocketHashByName);
    LwRtlFreeThreadPool(&gRdrRuntime.pThreadPool);

    /* Free the global mutex */
    if (gRdrRuntime.bLockConstructed)
    {
        pthread_mutex_destroy(&gRdrRuntime.Lock);
        gRdrRuntime.bLockConstructed = FALSE;
    }

    return status;
}
Example #6
0
NTSTATUS
LwRtlCreateThreadPool(
    PLW_THREAD_POOL* ppPool,
    PLW_THREAD_POOL_ATTRIBUTES pAttrs
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    PLW_THREAD_POOL pPool = NULL;
    int i = 0;
    int numCpus = 0;

    status = LW_RTL_ALLOCATE_AUTO(&pPool);
    GOTO_ERROR_ON_STATUS(status);

    status = LwErrnoToNtStatus(pthread_mutex_init(&pPool->Lock, NULL));
    GOTO_ERROR_ON_STATUS(status);

    status = LwErrnoToNtStatus(pthread_cond_init(&pPool->Event, NULL));
    GOTO_ERROR_ON_STATUS(status);

    numCpus = LwRtlGetCpuCount();

    if (GetDelegateAttr(pAttrs))
    {
        status = AcquireDelegatePool(&pPool->pDelegate);
        GOTO_ERROR_ON_STATUS(status);
    }
    else
    {
        pPool->ulEventThreadCount = GetTaskThreadsAttr(pAttrs, numCpus);

        if (pPool->ulEventThreadCount)
        {
            status = LW_RTL_ALLOCATE_ARRAY_AUTO(
                &pPool->pEventThreads,
                pPool->ulEventThreadCount);
            GOTO_ERROR_ON_STATUS(status);

            for (i = 0; i < pPool->ulEventThreadCount; i++)
            {
                status = InitEventThread(pPool, pAttrs, &pPool->pEventThreads[i], i % numCpus);
                GOTO_ERROR_ON_STATUS(status);
            }
        }
    }

    status = InitWorkThreads(&pPool->WorkThreads, pAttrs, numCpus);
    GOTO_ERROR_ON_STATUS(status);

    *ppPool = pPool;

cleanup:

    return status;

error:

    LwRtlFreeThreadPool(&pPool);

    goto cleanup;
}
Example #7
0
int
main(
    int argc,
    char** ppszArgv
    )
{
    DWORD dwError = 0;

    /* Parse command line */
    dwError = LwSmParseArguments(argc, ppszArgv);
    BAIL_ON_ERROR(dwError);

    /* Block all signals */
    dwError = LwNtStatusToWin32Error(LwRtlBlockSignals());
    BAIL_ON_ERROR(dwError);

    /* Fork into background if running as a daemon */
    if (gState.bStartAsDaemon)
    {
        dwError = LwSmDaemonize();
        BAIL_ON_ERROR(dwError);
    }

    /* If we're starting as the control server, acquire lock */
    if (!gState.bContainer)
    {
        dwError = LwSmControlLock();
        BAIL_ON_ERROR(dwError);
    }

    /* Create thread pool */
    dwError = LwNtStatusToWin32Error(LwRtlCreateThreadPool(&gpPool, NULL));
    BAIL_ON_ERROR(dwError);

    dwError = LWNetExtendEnvironmentForKrb5Affinity(FALSE);
    BAIL_ON_ERROR(dwError);

    /* Mac OS X - avoid potential circular calls into directory services */
    dwError = LwDsCacheAddPidException(getpid());
    BAIL_ON_ERROR(dwError);

    /* Initialize i18n */
    setlocale(LC_ALL, "");

    /* Initialize logging subsystem */
    LwSmLogInit();

    /* Set up logging */
    dwError = LwSmConfigureLogging(gState.pName);
    BAIL_ON_ERROR(dwError);

    /* Initialize the container subsystem */
    dwError = LwSmContainerInit();
    BAIL_ON_ERROR(dwError);

    /* Initialize the service table subsystem */
    dwError = LwSmTableInit();
    BAIL_ON_ERROR(dwError);

    /* Enter main loop */
    dwError = LwSmMain();
    BAIL_ON_ERROR(dwError);

error:

    /* If we are starting as a daemon and have not
       notified the parent process yet, notify it
       of an error now */
    if (gState.bStartAsDaemon && !gState.bNotified)
    {
        LwSmNotify(dwError);
    }

    /* Shut down service table */
    LwSmTableShutdown();

    /* Shut down containers */
    LwSmContainerShutdown();

    /* Shut down logging */
    LwSmLoggingShutdown();

    /* Remove DS cache exception */
    LwDsCacheRemovePidException(getpid());

    /* Free thread pool */
    LwRtlFreeThreadPool(&gpPool);

    /* Close control file if it is open */
    if (gState.ControlLock >= 0)
    {
        close(gState.ControlLock);
    }

    if (dwError)
    {
        fprintf(stderr, "Error: %s (%d)\n", LwWin32ExtErrorToName(dwError), (int) dwError);
    }

    return dwError ? 1 : 0;
}
Example #8
0
static
DWORD
LwSmCmdTapLog(
    int argc,
    char** pArgv
    )
{
    DWORD error = ERROR_SUCCESS;
    PLW_THREAD_POOL pPool = NULL;
    PLW_TASK pTask = NULL;
    BOOLEAN bResetLogger = FALSE;
    BOOLEAN bRmPipe = FALSE;
    LW_SM_LOGGER_TYPE oldLogger = 0;
    PSTR pOldTarget = NULL;
    LW_SM_LOG_LEVEL oldLevel = 0;
    LW_SM_LOG_LEVEL newLevel = 0;
    PSTR pFacility = NULL;
    LW_SERVICE_HANDLE hHandle = NULL;
    PWSTR pServiceName = NULL;
    PSTR pFifo = NULL;
    int FifoFd = -1;

    if (argc < 4)
    {
        error = LW_ERROR_INVALID_PARAMETER;
        BAIL_ON_ERROR(error);
    }

    if (strcmp(pArgv[1], "-"))
    {
        error = LwMbsToWc16s(pArgv[1], &pServiceName);
        BAIL_ON_ERROR(error);

        error = LwSmAcquireServiceHandle(pServiceName, &hHandle);
        BAIL_ON_ERROR(error);
    }

    if (strcmp(pArgv[2], "-"))
    {
        pFacility = pArgv[2];
    }

    error = LwSmLogLevelNameToLogLevel(pArgv[3], &newLevel);
    BAIL_ON_ERROR(error);

    error = LwSmGetServiceLogState(hHandle, pFacility, &oldLogger, &pOldTarget, &oldLevel);
    BAIL_ON_ERROR(error);

    error = LwAllocateStringPrintf(&pFifo, "/tmp/.lwsm-log-tap-%lu", (unsigned long) getpid());
    BAIL_ON_ERROR(error);

    LwRtlBlockSignals();
    if (mknod(pFifo, S_IRUSR | S_IWUSR | S_IFIFO, 0) < 0)
    {
        error = LwErrnoToWin32Error(errno);
        BAIL_ON_ERROR(error);
    }
    bRmPipe = TRUE;

    if ((FifoFd = open(pFifo, O_RDONLY | O_NONBLOCK)) < 0)
    {
        error = LwErrnoToWin32Error(errno);
        BAIL_ON_ERROR(error);
    }

    if (fcntl(FifoFd, F_SETFL, O_NONBLOCK) < 0)
    {
        error = LwErrnoToWin32Error(errno);
        BAIL_ON_ERROR(error);
    }

    error = LwSmSetServiceLogTarget(hHandle, pFacility, LW_SM_LOGGER_FILE, pFifo);
    BAIL_ON_ERROR(error);
    bResetLogger = TRUE;

    error = LwSmSetServiceLogLevel(hHandle, pFacility, newLevel);
    BAIL_ON_ERROR(error);

    error = LwNtStatusToWin32Error(LwRtlCreateThreadPool(&pPool, NULL));
    BAIL_ON_ERROR(error);

    error = LwNtStatusToWin32Error(LwRtlCreateTask(pPool, &pTask, NULL, LogTapper, &FifoFd));
    BAIL_ON_ERROR(error);

    LwRtlWakeTask(pTask);

    error = LwNtStatusToWin32Error(LwRtlMain());
    BAIL_ON_ERROR(error);

error:

    if (pTask)
    {
        LwRtlCancelTask(pTask);
        LwRtlWaitTask(pTask);
        LwRtlReleaseTask(&pTask);
    }

    LwRtlFreeThreadPool(&pPool);

    if (bResetLogger)
    {
        error = LwSmSetServiceLogLevel(hHandle, pFacility, oldLevel);
        BAIL_ON_ERROR(error);

        error = LwSmSetServiceLogTarget(hHandle, pFacility, oldLogger, pOldTarget);
        BAIL_ON_ERROR(error);
    }

    if (pOldTarget)
    {
        LwSmFreeLogTarget(pOldTarget);
    }

    if (FifoFd >= 0)
    {
        close(FifoFd);
    }

    if (bRmPipe)
    {
        unlink(pFifo);
    }

    LW_SAFE_FREE_MEMORY(pFifo);

    return error;
}
Example #9
0
NTSTATUS
AcquireDelegatePool(
    PLW_THREAD_POOL* ppPool
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    LW_THREAD_POOL_ATTRIBUTES attrs =
    {
        .bDelegateTasks = FALSE,
        .lTaskThreads = -1,
        .lWorkThreads = 0,
        .ulTaskThreadStackSize = 0,
        .ulWorkThreadStackSize = 0
    };

    if (getenv("LW_GLOBAL_TASK_THREADS"))
    {
        attrs.lTaskThreads = (LONG) atoi(getenv("LW_GLOBAL_TASK_THREADS"));
    }

    pthread_mutex_lock(&gpDelegateLock);

    if (!gpDelegatePool)
    {
        status = LwRtlCreateThreadPool(&gpDelegatePool, &attrs);
        GOTO_ERROR_ON_STATUS(status);

        gpDelegatePoolRefCount = 1;
    }
    else
    {
        gpDelegatePoolRefCount++;
    }

    *ppPool = gpDelegatePool;

cleanup:

    pthread_mutex_unlock(&gpDelegateLock);

    return status;

error:

    goto cleanup;
}

VOID
ReleaseDelegatePool(
    PLW_THREAD_POOL* ppPool
    )
{
    BOOLEAN bFree = FALSE;

    if (*ppPool)
    {
        pthread_mutex_lock(&gpDelegateLock);

        assert(*ppPool == gpDelegatePool);

        if (--gpDelegatePoolRefCount == 0)
        {
            gpDelegatePool = NULL;
            bFree = TRUE;
        }

        pthread_mutex_unlock(&gpDelegateLock);
    }

    if (bFree)
    {
        LwRtlFreeThreadPool(ppPool);
    }
}