VirtualBox

Changeset 52789 in vbox for trunk/src/VBox/Devices


Ignore:
Timestamp:
Sep 18, 2014 4:08:18 PM (10 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
96175
Message:

VMMDev/Main, Additions: Guest heartbeat implementation. VMMDev reports to host log if missed heartbeat from the guest.

Location:
trunk/src/VBox/Devices
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/VMMDev/VMMDev.cpp

    r52667 r52789  
    55
    66/*
    7  * Copyright (C) 2006-2013 Oracle Corporation
     7 * Copyright (C) 2006-2014 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    9090 *  This doesn't have the config part. */
    9191#define VMMDEV_SAVED_STATE_VERSION_VBOX_30                      11
     92/** Default interval in nanoseconds between guest heartbeats.
     93 *  Used when no HeartbeatInterval is set in CFGM and for setting
     94 *  HB check timer if the guest's heartbeat frequency is less than 1Hz. */
     95#define HEARTBEAT_DEFAULT_INTERVAL            UINT64_C(2000000000)
    9296
    9397
     
    350354
    351355    return VINF_SUCCESS;
     356}
     357
     358
     359/**
     360 * Resets heartbeat timer.
     361 *
     362 * @param   pThis           The VMMDev state.
     363 * @returns VBox status code.
     364 */
     365static int vmmDevHeartbeatTimerReset(PVMMDEV pThis)
     366{
     367    if (pThis->fHBCheckEnabled)
     368        return TMTimerSetNano(pThis->pHBCheckTimer, pThis->u64HeartbeatTimeout);
     369
     370    return VINF_SUCCESS;
     371}
     372
     373
     374/**
     375 * Handles VMMDevReq_GuestHeartbeat.
     376 *
     377 * @returns VBox status code that the guest should see.
     378 * @param   pThis    The VMMDev instance data.
     379 */
     380static int vmmDevReqHandler_GuestHeartbeat(PVMMDEV pThis)
     381{
     382    int rc = VINF_SUCCESS;
     383
     384    if (pThis->fHBCheckEnabled)
     385    {
     386        ASMAtomicWriteU64(&pThis->uLastHBTime, TMTimerGetNano(pThis->pHBCheckTimer));
     387        if (pThis->fHasMissedHB)
     388        {
     389            LogRel(("vmmDevReqHandler_GuestHeartBeat: guest is alive\n"));
     390            ASMAtomicWriteBool(&pThis->fHasMissedHB, false);
     391        }
     392        rc = vmmDevHeartbeatTimerReset(pThis);
     393    }
     394    return rc;
     395}
     396
     397
     398/**
     399 * Guest heartbeat check timer. Fires if there are no heartbeats for certain time.
     400 * Timer is set in vmmDevHeartbeatTimerReset.
     401 */
     402static DECLCALLBACK(void) vmmDevHeartBeatCheckTimer(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser)
     403{
     404    PVMMDEV pThis = (PVMMDEV) pvUser;
     405    if (pThis->fHBCheckEnabled)
     406    {
     407        uint64_t interval = TMTimerGetNano(pTimer) - pThis->uLastHBTime;
     408        if (!pThis->fHasMissedHB && interval >= pThis->u64HeartbeatInterval)
     409        {
     410            LogRel(("vmmDevHeartBeatCheckTimer: guest seems to be not responding, last heartbeat received %RU64 sec ago\n", interval / 1000000000));
     411            ASMAtomicWriteBool(&pThis->fHasMissedHB, true);
     412        }
     413    }
     414}
     415
     416
     417/**
     418 * Handles VMMDevReq_HeartbeatConfigure.
     419 *
     420 * @returns VBox status code that the guest should see.
     421 * @param   pThis     The VMMDev instance data.
     422 * @param   pReqHdr   The header of the request to handle.
     423 */
     424static int vmmDevReqHandler_HeartbeatConfigure(PVMMDEV pThis, VMMDevRequestHeader *pReqHdr)
     425{
     426    AssertMsgReturn(pReqHdr->size == sizeof(VMMDevReqHeartbeat), ("%u\n", pReqHdr->size), VERR_INVALID_PARAMETER);
     427    VMMDevReqHeartbeat *pReq = (VMMDevReqHeartbeat *)pReqHdr;
     428    int rc;
     429
     430    pReq->cNsInterval = pThis->u64HeartbeatInterval;
     431
     432    if (pReq->fEnabled != pThis->fHBCheckEnabled)
     433    {
     434        ASMAtomicWriteBool(&pThis->fHBCheckEnabled, pReq->fEnabled);
     435        if (pReq->fEnabled)
     436        {
     437            /* set first timer explicitly */
     438            rc = vmmDevHeartbeatTimerReset(pThis);
     439            if (RT_SUCCESS(rc))
     440            {
     441                LogRel(("Heartbeat checking timer has been set to trigger every %RU64 sec\n", pThis->u64HeartbeatInterval / 500000000));
     442            }
     443            else
     444                LogRel(("Cannot create heartbeat check timer, rc=%Rrc\n", rc));
     445        }
     446        else
     447        {
     448            rc = TMTimerStop(pThis->pHBCheckTimer);
     449            LogRel(("Heartbeat checking timer has been stopped, rc=%Rrc\n", rc));
     450        }
     451    }
     452    else
     453    {
     454        LogRel(("vmmDevReqHandler_HeartbeatConfigure: enabled=%d\n", pThis->fHBCheckEnabled));
     455        rc = VINF_SUCCESS;
     456    }
     457
     458    return rc;
    352459}
    353460
     
    25172624        }
    25182625
     2626        case VMMDevReq_GuestHeartbeat:
     2627            pReqHdr->rc = vmmDevReqHandler_GuestHeartbeat(pThis);
     2628            break;
     2629
     2630        case VMMDevReq_HeartbeatConfigure:
     2631            pReqHdr->rc = vmmDevReqHandler_HeartbeatConfigure(pThis, pReqHdr);
     2632            break;
     2633
    25192634        default:
    25202635        {
     
    38233938                                N_("Configuration error: Failed querying \"GuestCoreDumpCount\" as a 32-bit unsigned integer"));
    38243939
     3940    rc = CFGMR3QueryU64Def(pCfg, "HeartbeatInterval", &pThis->u64HeartbeatInterval, HEARTBEAT_DEFAULT_INTERVAL);
     3941    if (RT_FAILURE(rc))
     3942        return PDMDEV_SET_ERROR(pDevIns, rc,
     3943                                N_("Configuration error: Failed querying \"HeartbeatInterval\" as a 64-bit unsigned integer"));
     3944
     3945    rc = CFGMR3QueryU64Def(pCfg, "HeartbeatTimeout", &pThis->u64HeartbeatTimeout, pThis->u64HeartbeatInterval * 2);
     3946    if (RT_FAILURE(rc))
     3947        return PDMDEV_SET_ERROR(pDevIns, rc,
     3948                                N_("Configuration error: Failed querying \"HeartbeatTimeout\" as a 64-bit unsigned integer"));
     3949
    38253950#ifndef VBOX_WITHOUT_TESTING_FEATURES
    38263951    rc = CFGMR3QueryBoolDef(pCfg, "TestingEnabled", &pThis->fTestingEnabled, false);
     
    39674092                                NULL, vmmdevSaveExec, NULL,
    39684093                                NULL, vmmdevLoadExec, vmmdevLoadStateDone);
     4094    AssertRCReturn(rc, rc);
     4095
     4096    /*
     4097     * Create heartbeat checking timer.
     4098     */
     4099    rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, vmmDevHeartBeatCheckTimer, pThis,
     4100                        TMTIMER_FLAGS_NO_CRIT_SECT, "HB Check Timer", &pThis->pHBCheckTimer);
    39694101    AssertRCReturn(rc, rc);
    39704102
  • trunk/src/VBox/Devices/VMMDev/VMMDevState.h

    r51520 r52789  
    359359    RTTEST                  hTestingTest;
    360360#endif /* !VBOX_WITHOUT_TESTING_FEATURES */
     361
     362    /** Timestamp of the last heartbeat from guest in nanosec. */
     363    uint64_t volatile   uLastHBTime;
     364    /** Indicates whether we missed HB from guest on last check. */
     365    bool volatile       fHasMissedHB;
     366    /** Indicates whether heartbeat check is active. */
     367    bool volatile       fHBCheckEnabled;
     368    /** Alignment padding. */
     369    bool                afAlignment8[6];
     370    /** Guest heartbeat interval in nanoseconds. */
     371    uint64_t            u64HeartbeatInterval;
     372    /** Guest heartbeat timeout in nanoseconds. */
     373    uint64_t            u64HeartbeatTimeout;
     374    /** Timer for checking guest heart beat. */
     375    PTMTIMERR3          pHBCheckTimer;
    361376} VMMDevState;
    362377typedef VMMDevState VMMDEV;
  • trunk/src/VBox/Devices/testcase/tstDeviceStructSizeRC.cpp

    r52508 r52789  
    88
    99/*
    10  * Copyright (C) 2006-2012 Oracle Corporation
     10 * Copyright (C) 2006-2014 Oracle Corporation
    1111 *
    1212 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    16591659    GEN_CHECK_OFF(VMMDEV, TestingData.Value.u32Unit);
    16601660    GEN_CHECK_OFF(VMMDEV, TestingData.Value.szName);
     1661    GEN_CHECK_OFF(VMMDEV, uLastHBTime);
     1662    GEN_CHECK_OFF(VMMDEV, fHasMissedHB);
     1663    GEN_CHECK_OFF(VMMDEV, fHBCheckEnabled);
     1664    GEN_CHECK_OFF(VMMDEV, u64HeartbeatInterval);
     1665    GEN_CHECK_OFF(VMMDEV, u64HeartbeatTimeout);
     1666    GEN_CHECK_OFF(VMMDEV, pHBCheckTimer);
    16611667
    16621668#ifdef VBOX_WITH_BUSLOGIC
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette