Beispiel #1
0
static
VOID
Shutdown(
    PVOID pUnused
    )
{
    DWORD dwError = 0;

    if (!gState.bContainer)
    {
        /* Shut down all running services  */
        dwError = LwSmShutdownServices();
        BAIL_ON_ERROR(dwError);
    }

    /* Stop IPC server */
    dwError = LwSmStopIpcServer();
    BAIL_ON_ERROR(dwError);

    /* Exit from main loop */
    LwRtlExitMain(STATUS_SUCCESS);

    return;

error:

    LwRtlExitMain(STATUS_UNSUCCESSFUL);
}
Beispiel #2
0
static
VOID
Startup(
    PVOID pUnused
    )
{
    DWORD dwError = 0;

    SM_LOG_INFO("Likewise Service Manager starting up");

    /* Initialize IPC system and direct container endpoint */
    dwError = LwSmIpcInit();
    BAIL_ON_ERROR(dwError);

    if (!gState.bContainer)
    {
        /* Bootstrap ourselves by adding and starting any
           services we need to run (e.g. registry) */
        dwError = LwSmBootstrap();
        BAIL_ON_ERROR(dwError);

        /* Read configuration and populate service table */
        dwError = LwSmPopulateTable();
        BAIL_ON_ERROR(dwError);
    }

    /* Start IPC servers */
    dwError = LwSmStartIpcServer();
    BAIL_ON_ERROR(dwError);

    /* If we are starting as a daemon, indicate that we
       are ready to the parent process.  This ensures that
       the parent does not exit until we are actually accepting
       IPC connections */
    if (gState.bStartAsDaemon)
    {
        dwError = LwSmNotify(0);
        BAIL_ON_ERROR(dwError);
        gState.bNotified = TRUE;
    }

    SM_LOG_INFO("Likewise Service Manager startup complete");

    return;

error:

    LwRtlExitMain(STATUS_UNSUCCESSFUL);
}
Beispiel #3
0
static
VOID
RefreshConfig(
    PVOID pUnused
    )
{
    DWORD dwError = 0;

    dwError = LwSmPopulateTable();
    BAIL_ON_ERROR(dwError);

    return;

error:

    LwRtlExitMain(STATUS_UNSUCCESSFUL);
}
Beispiel #4
0
static
VOID
MainTask(
    PLW_TASK pTask,
    PVOID pContext,
    LW_TASK_EVENT_MASK WakeMask,
    PLW_TASK_EVENT_MASK pWaitMask,
    PLONG64 pllTime
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    siginfo_t info;

    if (WakeMask & LW_TASK_EVENT_CANCEL)
    {
        *pWaitMask = LW_TASK_EVENT_COMPLETE;
        goto cleanup;
    }
    else if (WakeMask & LW_TASK_EVENT_INIT)
    {
        status = LwRtlSetTaskUnixSignal(pTask, SIGTERM, TRUE);
        BAIL_ON_ERROR(status);

        status = LwRtlSetTaskUnixSignal(pTask, SIGINT, TRUE);
        BAIL_ON_ERROR(status);

        status = LwRtlSetTaskUnixSignal(pTask, SIGHUP, TRUE);
        BAIL_ON_ERROR(status);

        status = LwRtlQueueWorkItem(gpPool, Startup, NULL, 0);
        BAIL_ON_ERROR(status);

        *pWaitMask = LW_TASK_EVENT_UNIX_SIGNAL;
    }
    else if (WakeMask & LW_TASK_EVENT_UNIX_SIGNAL)
    {
        while (LwRtlNextTaskUnixSignal(pTask, &info))
        {
            switch(info.si_signo)
            {
            case SIGTERM:
            case SIGINT:
                SM_LOG_VERBOSE(info.si_signo == SIGINT ?
                    "Shutting down on SIGINT" :
                    "Shutting down on SIGTERM");
                /* Shutting down stops all running services, which is a blocking operation */
                status = LwRtlQueueWorkItem(gpPool, Shutdown, NULL, 0);
                BAIL_ON_ERROR(status);
                *pWaitMask = LW_TASK_EVENT_COMPLETE;
                goto cleanup;
            case SIGHUP:
                SM_LOG_VERBOSE("Refreshing configuration on SIGHUP");
                /* Refreshing config reads from the registry, which is a blocking operation */
                status = LwRtlQueueWorkItem(gpPool, RefreshConfig, NULL, 0);
                BAIL_ON_ERROR(status);
                break;
            default:
                break;
            }
        }

        *pWaitMask = LW_TASK_EVENT_UNIX_SIGNAL;
    }

cleanup:

    return;

error:

    if (status)
    {
        LwRtlExitMain(status);
        *pWaitMask = LW_TASK_EVENT_COMPLETE;
    }

    goto cleanup;
}
Beispiel #5
0
static
VOID
LogTapper(
    PLW_TASK pTask,
    PVOID pContext,
    LW_TASK_EVENT_MASK WakeMask,
    LW_TASK_EVENT_MASK* pWaitMask,
    LONG64* pllTime
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    int FifoFd = *(int*) pContext;
    siginfo_t info = {0};
    char buffer[2048] = {0};
    ssize_t count = 0;

    if (WakeMask & LW_TASK_EVENT_CANCEL)
    {
        status = STATUS_CANCELLED;
        BAIL_ON_ERROR(status);
    }
    else if (WakeMask & LW_TASK_EVENT_INIT)
    {
        status = LwRtlSetTaskUnixSignal(pTask, SIGINT, TRUE);
        BAIL_ON_ERROR(status);

        status = LwRtlSetTaskUnixSignal(pTask, SIGTERM, TRUE);
        BAIL_ON_ERROR(status);

        status = LwRtlSetTaskFd(pTask, FifoFd, LW_TASK_EVENT_FD_READABLE);
        BAIL_ON_ERROR(status);
    }
    else if (WakeMask & LW_TASK_EVENT_UNIX_SIGNAL)
    {
        while (LwRtlNextTaskUnixSignal(pTask, &info))
        {
            if (info.si_signo == SIGINT || info.si_signo == SIGTERM)
            {
                status = STATUS_CANCELLED;
                BAIL_ON_ERROR(status);
            }
        }
    }
    else if (WakeMask & LW_TASK_EVENT_FD_READABLE)
    {
        do
        {
            do
            {
                count = read(FifoFd, buffer, sizeof(buffer));
            } while (count < 0 && errno == EINTR);

            if (count == 0)
            {
                status = STATUS_END_OF_FILE;
                BAIL_ON_ERROR(status);
            }
            else if (count > 0)
            {
                count = write(1, buffer, count);
                if (count < 0)
                {
                    status = LwErrnoToNtStatus(errno);
                    BAIL_ON_ERROR(status);
                }
            }
            else if (errno != EAGAIN)
            {
                status = LwErrnoToNtStatus(errno);
                BAIL_ON_ERROR(status);
            }
        } while (count > 0);
    }

    *pWaitMask = LW_TASK_EVENT_FD_READABLE | LW_TASK_EVENT_UNIX_SIGNAL;

cleanup:

    return;

error:

    *pWaitMask = LW_TASK_EVENT_COMPLETE;
    LwRtlSetTaskFd(pTask, FifoFd, 0);
    LwRtlExitMain(status);

    goto cleanup;
}