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 DWORD LwSmShutdownServices( VOID ) { DWORD dwError = 0; PWSTR* ppwszServiceNames = NULL; size_t i = 0; PSM_TABLE_ENTRY pEntry = NULL; SM_LOG_INFO("Shutting down running services"); dwError = LwSmTableEnumerateEntries(&ppwszServiceNames); BAIL_ON_ERROR(dwError); for (i = 0; ppwszServiceNames[i]; i++) { dwError = LwSmTableGetEntry(ppwszServiceNames[i], &pEntry); BAIL_ON_ERROR(dwError); dwError = LwSmShutdownService(pEntry); if (dwError) { /* Ignore errors and try to shut down everything we can */ SM_LOG_WARNING("Could not shut down service: %u\n", (unsigned int) dwError); dwError = 0; } LwSmTableReleaseEntry(pEntry); pEntry = NULL; } cleanup: if (ppwszServiceNames) { LwSmFreeStringList(ppwszServiceNames); } if (pEntry) { LwSmTableReleaseEntry(pEntry); } return dwError; error: goto cleanup; }
DWORD LwSmTableStopEntry( PSM_TABLE_ENTRY pEntry ) { DWORD dwError = 0; BOOLEAN bLocked = FALSE; LW_SERVICE_STATUS status = {.state = LW_SERVICE_STATE_RUNNING}; DWORD dwAttempts = 0; PSTR pszServiceName = NULL; LOCK(bLocked, pEntry->pLock); if (!pEntry->bValid) { dwError = LW_ERROR_INVALID_HANDLE; BAIL_ON_ERROR(dwError); } while (status.state != LW_SERVICE_STATE_STOPPED) { dwError = LwSmTablePollEntry(pEntry, &status); BAIL_ON_ERROR(dwError); switch (status.state) { case LW_SERVICE_STATE_RUNNING: case LW_SERVICE_STATE_DEAD: pEntry->StartAttempts = 0; /* A service that is dead should go directly to the stop state when requested */ if (dwAttempts == 0) { LW_SAFE_FREE_MEMORY(pszServiceName); dwError = LwWc16sToMbs(pEntry->pInfo->pwszName, &pszServiceName); BAIL_ON_ERROR(dwError); SM_LOG_INFO("Stopping service: %s", pszServiceName); UNLOCK(bLocked, pEntry->pLock); dwError = pEntry->pVtbl->pfnStop(&pEntry->object); LOCK(bLocked, pEntry->pLock); BAIL_ON_ERROR(dwError); dwAttempts++; } else { dwError = LW_ERROR_SERVICE_UNRESPONSIVE; BAIL_ON_ERROR(dwError); } break; case LW_SERVICE_STATE_STOPPED: break; case LW_SERVICE_STATE_STARTING: case LW_SERVICE_STATE_STOPPING: dwError = LwSmTableWaitEntryChanged(pEntry); BAIL_ON_ERROR(dwError); break; case LW_SERVICE_STATE_PAUSED: dwError = LW_ERROR_INVALID_SERVICE_TRANSITION; BAIL_ON_ERROR(dwError); break; } } cleanup: LW_SAFE_FREE_MEMORY(pszServiceName); UNLOCK(bLocked, pEntry->pLock); return dwError; error: goto cleanup; }
DWORD LwSmTableStartEntry( PSM_TABLE_ENTRY pEntry ) { DWORD dwError = 0; BOOLEAN bLocked = FALSE; LW_SERVICE_STATUS status = {.state = LW_SERVICE_STATE_DEAD}; DWORD dwAttempts = 0; PSTR pszServiceName = NULL; LOCK(bLocked, pEntry->pLock); if (!pEntry->bValid) { dwError = LW_ERROR_INVALID_HANDLE; BAIL_ON_ERROR(dwError); } while (status.state != LW_SERVICE_STATE_RUNNING) { UNLOCK(bLocked, pEntry->pLock); dwError = pEntry->pVtbl->pfnGetStatus(&pEntry->object, &status); LOCK(bLocked, pEntry->pLock); BAIL_ON_ERROR(dwError); switch (status.state) { case LW_SERVICE_STATE_RUNNING: pEntry->StartAttempts = 1; break; case LW_SERVICE_STATE_STOPPED: case LW_SERVICE_STATE_DEAD: pEntry->StartAttempts = 0; if (dwAttempts == 0) { LW_SAFE_FREE_MEMORY(pszServiceName); dwError = LwWc16sToMbs(pEntry->pInfo->pwszName, &pszServiceName); BAIL_ON_ERROR(dwError); SM_LOG_INFO("Starting service: %s", pszServiceName); if (pEntry->bDirty) { dwError = LwSmTableReconstructEntry(pEntry); BAIL_ON_ERROR(dwError); } UNLOCK(bLocked, pEntry->pLock); dwError = pEntry->pVtbl->pfnStart(&pEntry->object); LOCK(bLocked, pEntry->pLock); BAIL_ON_ERROR(dwError); dwAttempts++; } else { dwError = LW_ERROR_SERVICE_UNRESPONSIVE; BAIL_ON_ERROR(dwError); } break; case LW_SERVICE_STATE_STARTING: case LW_SERVICE_STATE_STOPPING: dwError = LwSmTableWaitEntryChanged(pEntry); BAIL_ON_ERROR(dwError); break; case LW_SERVICE_STATE_PAUSED: dwError = LW_ERROR_INVALID_SERVICE_TRANSITION; BAIL_ON_ERROR(dwError); break; } } cleanup: LW_SAFE_FREE_MEMORY(pszServiceName); UNLOCK(bLocked, pEntry->pLock); return dwError; error: goto cleanup; }