Esempio n. 1
0
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;
}
Esempio n. 2
0
VOID
LwSmTableNotifyEntryStateChanged(
    PSM_TABLE_ENTRY pEntry,
    LW_SERVICE_STATE state
    )
{
    DWORD error = ERROR_SUCCESS;
    BOOLEAN bLocked = FALSE;
    PSM_LINK pLink = NULL;
    PSM_LINK pNext = NULL;
    PSM_ENTRY_NOTIFY pNotify = NULL;
    PSTR pServiceName = NULL;
    time_t now = 0;
    
    LOCK(bLocked, pEntry->pLock);

    for (pLink = LwSmLinkBegin(&pEntry->waiters);
         LwSmLinkValid(&pEntry->waiters, pLink);
         pLink = pNext)
    {
        pNext = LwSmLinkNext(pLink);
        pNotify = STRUCT_FROM_MEMBER(pLink, SM_ENTRY_NOTIFY, link);

        LwSmLinkRemove(pLink);

        pNotify->pfnNotifyEntryStateChange(state, pNotify->pData);

        LwFreeMemory(pNotify);
    }

    pthread_cond_broadcast(pEntry->pEvent);

    if (state == LW_SERVICE_STATE_DEAD && gState.bWatchdog)
    {
        now = time(NULL);
        if (now == (time_t) -1)
        {
            error = LwErrnoToWin32Error(errno);
            BAIL_ON_ERROR(error);
        }

        error = LwWc16sToMbs(pEntry->pInfo->pwszName, &pServiceName);
        BAIL_ON_ERROR(error);

        if (pEntry->StartAttempts >= 1 &&
            (now - pEntry->LastRestartPeriod) > RESTART_PERIOD)
        {
            pEntry->StartAttempts = 1;
            pEntry->LastRestartPeriod = now;
        }

        if (pEntry->StartAttempts > 0 && pEntry->StartAttempts < RESTART_LIMIT)
        {
            pEntry->StartAttempts++;
            pEntry->dwRefCount++;

            SM_LOG_WARNING(
                "Restarting dead service: %s (attempt %u/%u)",
                pServiceName,
                (unsigned int) pEntry->StartAttempts,
                (unsigned int) RESTART_LIMIT);


            error = LwNtStatusToWin32Error(LwRtlQueueWorkItem(gpPool, LwSmTableWatchdog, pEntry, 0));
            if (error)
            {
                pEntry->dwRefCount--;
            }
            BAIL_ON_ERROR(error);
        }
        else if (pEntry->StartAttempts >= 1)
        {
            SM_LOG_ERROR(
                "Service died: %s (restarted %u times in %lu seconds)",
                pServiceName,
                (unsigned int) pEntry->StartAttempts,
                (unsigned long) (now - pEntry->LastRestartPeriod));
        }
        else
        {
            SM_LOG_ERROR(
                "Service failed to start: %s",
                pServiceName);
        }
    }

error:

    UNLOCK(bLocked, pEntry->pLock);

    LW_SAFE_FREE_MEMORY(pServiceName);
}