Beispiel #1
0
void
VmDnsUnlockWrite(
    PVMDNS_RWLOCK  pLock
    )
{
    int* pWriteLockCount = VmDnsGetLockKey(&pLock->writeKey);
    if (!pWriteLockCount)
    {
        VMDNS_LOG_ERROR("Out of memory, can't decrement lock count.");
    }
    else
    {
        if (*pWriteLockCount ==1)
        {
            pthread_rwlock_unlock(&pLock->rwLock);
            VmDnsLog(VMDNS_LOG_LEVEL_DEBUG,
                    "[UNLOCK WRITE] result write count is %u.\n",
                    *pWriteLockCount);
        }

        if (*pWriteLockCount > 0)
        {
            (*pWriteLockCount)--;
            VmDnsLog(VMDNS_LOG_LEVEL_DEBUG, "[--WRITE %u]\n", *pWriteLockCount);
        }
        else
        {
            VmDnsLog(VMDNS_LOG_LEVEL_ERROR,
                     "Unexpected unlock write, write count is %u.\n",
                     *pWriteLockCount);
        }
    }
}
Beispiel #2
0
static
DWORD
VmDnsForwarderMetricsDelete(
    PVMDNS_FORWARDER_ENTRY    pForwarderEntry
    )
{
    DWORD dwError = 0;
    BAIL_ON_VMDNS_ERROR(dwError);

/*    dwError = VmMetricsHistogramDelete(
                          gVmDnsMetricsContext,
                          pForwarderEntry->ForwarderMetricsContext.pQueryDuration);
    BAIL_ON_VMDNS_ERROR(dwError);

    dwError = VmMetricsHistogramDelete(
                          gVmDnsMetricsContext,
                          pForwarderEntry->ForwarderMetricsContext.pUpdateDuration);
    BAIL_ON_VMDNS_ERROR(dwError);
*/

cleanup:
    return dwError;

error:
    VmDnsLog(VMDNS_LOG_LEVEL_ERROR, "%s failed, error (%d)", __FUNCTION__, dwError);
    goto cleanup;
}
Beispiel #3
0
int
VmDnsTryLockRead(
    PVMDNS_RWLOCK  pLock
    )
{
    int result = ERROR_BUSY;
    int* pWriteLockCount = VmDnsGetLockKey(&pLock->writeKey);
    int* pReadLockCount = VmDnsGetLockKey(&pLock->readKey);

    if (pWriteLockCount && pReadLockCount)
    {
        if (*pWriteLockCount > 0)
        {
            // Simply increment a read count but don't lock for read
            // as that would cause undefined behavior.
            result = 0;
            VmDnsLog(VMDNS_LOG_LEVEL_DEBUG,
                     "Lock read when already holding %u write lock.",
                     *pWriteLockCount);
        }
        else
        {
            if (*pReadLockCount == 0)
            {
                result = pthread_rwlock_tryrdlock(&pLock->rwLock);
                if (!result)
                {
                    VmDnsLog(VMDNS_LOG_LEVEL_DEBUG,
                             "Locked for read. Result read count: %u\n",
                             *pReadLockCount + 1);
                }
            }
            else
            {
                result = 0;
            }
        }

        if (!result)
        {
            (*pReadLockCount)++;
            VmDnsLog(VMDNS_LOG_LEVEL_DEBUG, "[++READ %u]\n", *pReadLockCount);
        }
    }

    return result;
}
Beispiel #4
0
DWORD
VmDnsCacheRemoveZoneProc(
    PVOID pData,
    PCSTR pszZone
    )
{
    PVMDNS_CACHE_CONTEXT pCacheContext = (PVMDNS_CACHE_CONTEXT) pData;
    PVMDNS_ZONE_OBJECT pZoneObject = NULL;
    DWORD dwError = 0;

    dwError = VmDnsCacheFindZone(pCacheContext, pszZone, &pZoneObject);
    BAIL_ON_VMDNS_ERROR_IF(dwError && dwError != ERROR_NOT_FOUND);

    if (dwError == ERROR_NOT_FOUND)
    {
        //already deleted (probably same node)
        VmDnsLog(
            VMDNS_LOG_LEVEL_DEBUG,
            "Zone (%s) already deleted from cache",
            pszZone
            );

        dwError = 0;
    }
    else
    {
        VmDnsLog(
            VMDNS_LOG_LEVEL_DEBUG,
            "Removing Zone (%s) From Cache",
            pszZone
            );

        dwError = VmDnsCacheRemoveZone(pCacheContext, pZoneObject);
        BAIL_ON_VMDNS_ERROR(dwError);
    }

cleanup:
    VmDnsZoneObjectRelease(pZoneObject);
    return dwError;

error:
    goto cleanup;
}
Beispiel #5
0
int
VmDnsTryLockWrite(
    PVMDNS_RWLOCK  pLock
    )
{
    int result = ERROR_BUSY;
    int* pWriteLockCount = VmDnsGetLockKey(&pLock->writeKey);
    int* pReadLockCount = VmDnsGetLockKey(&pLock->readKey);
    if (pWriteLockCount && pReadLockCount)
    {
        if (*pReadLockCount > 0)
        {
            VmDnsLog(VMDNS_LOG_LEVEL_DEBUG,
                    "Cannot wrlock with %u existing rdlock from same thread.\n",
                    *pReadLockCount);
            result = ERROR_POSSIBLE_DEADLOCK;
        }
        else
        {
            if (*pWriteLockCount <= 0)
            {
                result = pthread_rwlock_trywrlock(&pLock->rwLock);
                if (result)
                {
                    VmDnsLog(VMDNS_LOG_LEVEL_ERROR, "trywrlock returned %u\n", result);
                }
            }
            else
            {
                result = 0;
            }

            if (!result)
            {
                (*pWriteLockCount)++;
                VmDnsLog(VMDNS_LOG_LEVEL_ERROR, "[++WRITE %u]\n", *pWriteLockCount);
            }
        }
    }

    return result;
}
Beispiel #6
0
void
VmDnsLockWrite(
    PVMDNS_RWLOCK  pLock
    )
{
    int* pWriteLockCount = VmDnsGetLockKey(&pLock->writeKey);
    if (!pWriteLockCount)
    {
        VMDNS_LOG_WARNING("Out of memory, try plain locking.");
        pthread_rwlock_wrlock(&pLock->rwLock);
    }
    else
    {
        if (*pWriteLockCount == 0)
        {
            pthread_rwlock_wrlock(&pLock->rwLock);
            VmDnsLog(VMDNS_LOG_LEVEL_DEBUG, "[LOCK WRITE]");
        }
        (*pWriteLockCount)++;
        VmDnsLog(VMDNS_LOG_LEVEL_DEBUG, "[++WRITE %u]\n", *pWriteLockCount);
    }
}
Beispiel #7
0
void
VmDnsUnlockRead(
    PVMDNS_RWLOCK  pLock
    )
{
    int* pWriteLockCount = VmDnsGetLockKey(&pLock->writeKey);
    int* pReadLockCount = VmDnsGetLockKey(&pLock->readKey);

    if (!pWriteLockCount || !pReadLockCount)
    {
        VMDNS_LOG_ERROR("Out of memory, can't decrement lock count.");
    }
    else
    {
        if (*pWriteLockCount > 0)
        {
            VmDnsLog(VMDNS_LOG_LEVEL_DEBUG, "Read unlock while already holding write lock.");
        }
        else
        {
            if (*pReadLockCount ==1)
            {
                pthread_rwlock_unlock(&pLock->rwLock);
                VmDnsLog(VMDNS_LOG_LEVEL_DEBUG, "[UNLOCK READ]");
            }
        }

        if (*pReadLockCount > 0)
        {
            (*pReadLockCount)--;
            VmDnsLog(VMDNS_LOG_LEVEL_DEBUG, "[--READ %u]\n", *pReadLockCount);
        }
        else
        {
            VmDnsLog(VMDNS_LOG_LEVEL_ERROR, "Unexpected read unlock.");
        }
    }
}
Beispiel #8
0
void
VmDnsLockRead(
    PVMDNS_RWLOCK  pLock
    )
{
    int* pWriteLockCount = VmDnsGetLockKey(&pLock->writeKey);
    int* pReadLockCount = VmDnsGetLockKey(&pLock->readKey);

    if (!pWriteLockCount || !pReadLockCount)
    {
        VMDNS_LOG_WARNING("Out of memory, try plain locking.");
        pthread_rwlock_rdlock(&pLock->rwLock);
    }
    else
    {
        if (*pWriteLockCount > 0)
        {
            // Simply increment a read count but don't lock for read
            // as that would cause undefined behavior.
            VmDnsLog(VMDNS_LOG_LEVEL_DEBUG,
                     "Lock read when already holding %u write lock.",
                     *pWriteLockCount);
        }
        else
        {
            if (*pReadLockCount == 0)
            {
                pthread_rwlock_rdlock(&pLock->rwLock);
                VmDnsLog(VMDNS_LOG_LEVEL_DEBUG,
                         "Actually locking for read. Result read count: %u\n",
                         *pReadLockCount + 1);
            }
        }
        (*pReadLockCount)++;
        VmDnsLog(VMDNS_LOG_LEVEL_DEBUG, "[++READ %u]\n", *pReadLockCount);
    }
}
Beispiel #9
0
static
DWORD
VmDnsForwarderMetricsInit(
    PVMDNS_FORWARDER_ENTRY pForwarderEntry
    )
{
    DWORD dwError = 0;
    UINT64 buckets[] = {1, 10, 100, 300, 1000};
    VM_METRICS_LABEL labelDurationOps[2][2] = {{{"operation","query"},{"forwarder",""}},
                                               {{"operation","update"},{"forwarder",""}}};

    labelDurationOps[0][1].pszValue = pForwarderEntry->pszForwarder;
    labelDurationOps[1][1].pszValue = pForwarderEntry->pszForwarder;

    BAIL_ON_VMDNS_ERROR(dwError);

    dwError = VmMetricsHistogramNew(
                gVmDnsMetricsContext,
                "vmdns_forwarder_request_duration",
                labelDurationOps[0],
                2,
                "Forwarder Process Request Duration",
                buckets,
                5,
                &pForwarderEntry->ForwarderMetricsContext.pQueryDuration
                );
    BAIL_ON_VMDNS_ERROR(dwError);

    dwError = VmMetricsHistogramNew(
                gVmDnsMetricsContext,
                "vmdns_forwarder_request_duration",
                labelDurationOps[1],
                2,
                "Forwarder Process Request Duration",
                buckets,
                5,
                &pForwarderEntry->ForwarderMetricsContext.pUpdateDuration
                );
    BAIL_ON_VMDNS_ERROR(dwError);

cleanup:
    return dwError;

error:
    VmDnsLog(VMDNS_LOG_LEVEL_ERROR, "%s failed, error (%d)", __FUNCTION__, dwError);
    goto cleanup;
}
Beispiel #10
0
static
DWORD
VmDnsNotifyLikewiseServiceManager()
{
    DWORD dwError = ERROR_SUCCESS;
    PCSTR   pszSmNotify = NULL;
    int  ret = 0;
    int  notifyFd = -1;
    char notifyCode = 0;

    // interact with likewise service manager (start/stop control)
    if ((pszSmNotify = getenv("LIKEWISE_SM_NOTIFY")) != NULL)
    {
        notifyFd = atoi(pszSmNotify);

        do
        {
            ret = write(notifyFd, &notifyCode, sizeof(notifyCode));

        } while (ret != sizeof(notifyCode) && errno == EINTR);

        if (ret < 0)
        {
#define BUFFER_SIZE 1024
            char buffer[BUFFER_SIZE]= {0};
            int errorNumber = errno;

            VmDnsStringErrorA( buffer, BUFFER_SIZE, errorNumber );
            VmDnsLog( VMDNS_LOG_LEVEL_DEBUG,
                      "Could not notify service manager: %s (%i)",
                      buffer,
                      errorNumber);

            dwError = LwErrnoToWin32Error(errno);
            BAIL_ON_VMDNS_ERROR(dwError);
#undef BUFFER_SIZE
        }
    }

error:
    if(notifyFd != -1)
    {
        close(notifyFd);
    }

    return dwError;
}
Beispiel #11
0
DWORD
VmDnsCacheEvictEntryProc(
    PVMDNS_NAME_ENTRY  pNameEntry,
    PVMDNS_ZONE_OBJECT pZoneObject
    )
{
    //assumes locks for cache and hashmap are already held
    DWORD dwError = 0;

    //Remove if not SOA
    if (VmDnsStringCompareA(
                pZoneObject->pszName,
                pNameEntry->pszName,
                FALSE
                ) != 0)
    {
        dwError = VmDnsZoneRemoveNameEntry(
                            pZoneObject,
                            pNameEntry
                            );
        BAIL_ON_VMDNS_ERROR(dwError);

        VmDnsLog(
            VMDNS_LOG_LEVEL_DEBUG,
            "Purged (%s) from Zone (%s) Cache",
            pNameEntry->pszName,
            pZoneObject->pszName
            );
    }
    else
    {
        dwError = ERROR_INVALID_PARAMETER;
    }

cleanup:
    return dwError;

error:
    goto cleanup;
}
Beispiel #12
0
int
main(
    int     argc,
    char  * argv[])
{
    DWORD       dwError = 0;
    int         logLevel = VMDNS_LOG_LEVEL_INFO;
    PCSTR       pszLogFile = NULL;
    BOOLEAN     bEnableSysLog = FALSE;

    //dwError = VmDnsSrvUpdateConfig();
    //BAIL_ON_VMDNS_ERROR(dwError);

    dwError = VmDnsParseArgs(
                  argc,
                  argv,
                  &logLevel,
                  &pszLogFile,
                  &gVmdnsGlobals.iListenPort,
                  &bEnableSysLog,
                  NULL);
    if(dwError != ERROR_SUCCESS)
    {
        ShowUsage( argv[0] );
        BAIL_ON_VMDNS_ERROR(dwError);
    }

    vmdns_syslog_level = logLevel;
    if( bEnableSysLog != FALSE )
    {
        vmdns_syslog = 1;
    }

    if (pszLogFile)
    {
        dwError = VmDnsAllocateStringA(
                      pszLogFile,
                      &gVmdnsGlobals.pszLogFile);
        BAIL_ON_VMDNS_ERROR(dwError);
    }

    dwError = VmDnsConfigGetDword(VMDNS_KEY_VALUE_LOG_CAP, &gVmdnsGlobals.dwMaximumOldFiles);
    if (dwError)
    {
        gVmdnsGlobals.dwMaximumOldFiles = VMDNS_DEFAULT_LOG_CAP;
    }

    dwError = VmDnsConfigGetDword(VMDNS_KEY_VALUE_LOG_SIZE, &gVmdnsGlobals.dwMaxLogSizeBytes);
    if (dwError)
    {
        gVmdnsGlobals.dwMaxLogSizeBytes = VMDNS_DEFAULT_LOG_SIZE;
    }

    dwError = VmDnsLogInitialize(gVmdnsGlobals.pszLogFile,
                                 gVmdnsGlobals.dwMaximumOldFiles,
                                 gVmdnsGlobals.dwMaxLogSizeBytes);
    BAIL_ON_VMDNS_ERROR(dwError);

    VmDnsLog(VMDNS_LOG_LEVEL_INFO, "Vmdnsd: start" );

    VmDnsBlockSelectedSignals();

    dwError = VmDnsInit();
    BAIL_ON_VMDNS_ERROR(dwError);

    dwError = VmDnsNotifyLikewiseServiceManager();
    BAIL_ON_VMDNS_ERROR(dwError);

    VmDnsdStateSet(VMDNSD_RUNNING);

    // main thread waits on signals
    dwError = VmDnsHandleSignals();
    BAIL_ON_VMDNS_ERROR(dwError);

    VmDnsLog( VMDNS_LOG_LEVEL_INFO, "Vmdnsd exiting..." );

cleanup:

    VmDnsdStateSet(VMDNS_SHUTDOWN);

    VmDnsShutdown();

    VmDnsLog( VMDNS_LOG_LEVEL_INFO, "Vmdnsd: stop" );

    VmDnsLogTerminate();

    return dwError;

error:

    goto cleanup;
}
Beispiel #13
0
DWORD
VmDnsCacheSyncZoneProc(
    PVOID pData,
    PCSTR pszZone
    )
{
    PVMDNS_CACHE_CONTEXT pCacheContext = (PVMDNS_CACHE_CONTEXT) pData;
    PVMDNS_ZONE_OBJECT pZoneObject = NULL;
    DWORD dwError = 0;
    DWORD dwForwarderCount = 0;
    PSTR* ppszForwarders = NULL;

    dwError = VmDnsCacheFindZone(
                        pCacheContext,
                        pszZone,
                        &pZoneObject
                        );
    BAIL_ON_VMDNS_ERROR_IF(dwError && dwError != ERROR_NOT_FOUND);

    if (dwError == ERROR_NOT_FOUND)
    {
        dwError = VmDnsCacheLoadZoneFromStore(pCacheContext, pszZone);
        BAIL_ON_VMDNS_ERROR(dwError);

        VmDnsLog(
            VMDNS_LOG_LEVEL_DEBUG,
            "Added Zone %s to Cache",
            pszZone
            );
    }
    else if (pZoneObject && pZoneObject->zoneId == VMDNS_ZONE_ID_FORWARDER)
    {
        dwError = VmDnsStoreGetForwarders(
                    pszZone,
                    &dwForwarderCount,
                    &ppszForwarders);
        BAIL_ON_VMDNS_ERROR_IF(dwError && dwError != ERROR_NO_DATA);

        dwError = 0;

        if (dwForwarderCount > 0 && *ppszForwarders)
        {
            dwError = VmDnsSetForwarders(
                            pZoneObject->pForwarderContext,
                            pszZone,
                            dwForwarderCount,
                            ppszForwarders);
            BAIL_ON_VMDNS_ERROR(dwError);

            VmDnsFreeStringCountedArrayA(ppszForwarders, dwForwarderCount);
            ppszForwarders = NULL;
            dwForwarderCount = 0;
        }
    }

cleanup:
    VmDnsZoneObjectRelease(pZoneObject);

    if (ppszForwarders)
    {
        VmDnsFreeStringCountedArrayA(ppszForwarders, dwForwarderCount);
    }

    return dwError;

error:
    goto cleanup;
}
Beispiel #14
0
DWORD
VmDnsCachePurgeRecord(
    PVMDNS_ZONE_OBJECT pZoneObject,
    PCSTR              pszRecord,
    DWORD              dwCachePurgeEvent
    )
{
    PVMDNS_RECORD_LIST pList = NULL;
    DWORD dwError = 0;

    if (VmDnsStringCompareA(pZoneObject->pszName, pszRecord, FALSE) == 0)
    {
        //update SOA record
        dwError = VmDnsStoreGetRecords(
                        pZoneObject->pszName,
                        pZoneObject->pszName,
                        &pList
                        );
        BAIL_ON_VMDNS_ERROR(dwError);

        dwError = VmDnsZoneUpdateRecords(
                            pZoneObject,
                            pZoneObject->pszName,
                            pList
                            );
        BAIL_ON_VMDNS_ERROR(dwError);

        VmDnsLog(
            VMDNS_LOG_LEVEL_DEBUG,
            "Refreshed (%s) in Cache",
            pZoneObject->pszName
            );
    }
    else
    {
        dwError = VmDnsZonePurgeRecords(pZoneObject, pszRecord);
        BAIL_ON_VMDNS_ERROR_IF(dwError && dwError != ERROR_NOT_FOUND)

        if (dwError == ERROR_NOT_FOUND)
        {
            VmDnsLog(
                VMDNS_LOG_LEVEL_DEBUG,
                "Record (%s) not found in Cache",
                pszRecord
                );

            dwError = 0;
        }
        else
        {
            if (dwCachePurgeEvent == CACHE_PURGE_MODIFICATION)
            {
                VmMetricsCounterIncrement(gVmDnsCounterMetrics[CACHE_MODIFY_PURGE_COUNT]);
            }
            else if (dwCachePurgeEvent == CACHE_PURGE_REPLICATION)
            {
                VmMetricsCounterIncrement(gVmDnsCounterMetrics[CACHE_NOTIFY_PURGE_COUNT]);
            }

            VmDnsLog(
                VMDNS_LOG_LEVEL_DEBUG,
                "Succesfully Purged (%s) from Cache",
                pszRecord
                );
        }
    }

cleanup:
    if (pList)
    {
        VmDnsRecordListRelease(pList);
    }

    return dwError;

error:
    goto cleanup;
}