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); }
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); }
static VOID RefreshConfig( PVOID pUnused ) { DWORD dwError = 0; dwError = LwSmPopulateTable(); BAIL_ON_ERROR(dwError); return; error: LwRtlExitMain(STATUS_UNSUCCESSFUL); }
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; }
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; }