VirtualBox

Changeset 75853 in vbox for trunk/src/VBox/Additions


Ignore:
Timestamp:
Nov 30, 2018 7:26:42 PM (6 years ago)
Author:
vboxsync
Message:

GuestControl,HGCM,VBoxService: Save/restore related optimizations and changes. bugref:9313

Location:
trunk/src/VBox/Additions/common
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/common/VBoxGuest/lib/VBoxGuestR3LibGuestCtrl.cpp

    r75824 r75853  
    307307
    308308
    309 
    310309/**
    311310 * Peeks at the next host message, waiting for one to turn up.
     
    314313 * @retval  VERR_INTERRUPTED if interrupted.  Does the necessary cleanup, so
    315314 *          caller just have to repeat this call.
     315 * @retval  VERR_VM_RESTORED if the VM has been restored (idRestoreCheck).
    316316 *
    317317 * @param   idClient        The client ID returned by VbglR3GuestCtrlConnect().
     
    319319 * @param   pcParameters    Where to store the number  of parameters which will
    320320 *                          be received in a second call to the host.
    321  */
    322 VBGLR3DECL(int) VbglR3GuestCtrlMsgPeekWait(uint32_t idClient, uint32_t *pidMsg, uint32_t *pcParameters)
     321 * @param   pidRestoreCheck Pointer to the VbglR3GetSessionId() variable to use
     322 *                          for the VM restore check.  Optional.
     323 *
     324 * @note    Restore check is only performed optimally with a 6.0 host.
     325 */
     326VBGLR3DECL(int) VbglR3GuestCtrlMsgPeekWait(uint32_t idClient, uint32_t *pidMsg, uint32_t *pcParameters, uint64_t *pidRestoreCheck)
    323327{
    324328    AssertPtrReturn(pidMsg, VERR_INVALID_POINTER);
     
    328332    if (vbglR3GuestCtrlSupportsPeekGetCancel(idClient))
    329333    {
    330         HGCMMsgCmdWaitFor Msg;
    331         VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient, GUEST_MSG_PEEK_WAIT, 2);
    332         VbglHGCMParmUInt32Set(&Msg.msg, 0);
    333         VbglHGCMParmUInt32Set(&Msg.num_parms, 0);
    334         rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
     334        struct
     335        {
     336            VBGLIOCHGCMCALL Hdr;
     337            HGCMFunctionParameter idMsg;       /* Doubles as restore check on input. */
     338            HGCMFunctionParameter cParameters;
     339        } Msg;
     340        VBGL_HGCM_HDR_INIT(&Msg.Hdr, idClient, GUEST_MSG_PEEK_WAIT, 2);
     341        VbglHGCMParmUInt64Set(&Msg.idMsg, pidRestoreCheck ? *pidRestoreCheck : 0);
     342        VbglHGCMParmUInt32Set(&Msg.cParameters, 0);
     343        rc = VbglR3HGCMCall(&Msg.Hdr, sizeof(Msg));
    335344        LogRel(("VbglR3GuestCtrlMsgPeekWait -> %Rrc\n", rc));
    336345        if (RT_SUCCESS(rc))
    337346        {
    338             AssertMsgReturn(   Msg.msg.type       == VMMDevHGCMParmType_32bit
    339                             && Msg.num_parms.type == VMMDevHGCMParmType_32bit,
    340                             ("msg.type=%d num_parms.type=%d\n", Msg.msg.type, Msg.num_parms.type),
     347            AssertMsgReturn(   Msg.idMsg.type       == VMMDevHGCMParmType_64bit
     348                            && Msg.cParameters.type == VMMDevHGCMParmType_32bit,
     349                            ("msg.type=%d num_parms.type=%d\n", Msg.idMsg.type, Msg.cParameters.type),
    341350                            VERR_INTERNAL_ERROR_3);
    342351
    343             *pidMsg       = Msg.msg.u.value32;
    344             *pcParameters = Msg.num_parms.u.value32;
     352            *pidMsg       = (uint32_t)Msg.idMsg.u.value64;
     353            *pcParameters = Msg.cParameters.u.value32;
    345354            return rc;
    346355        }
     
    351360        if (rc == VERR_INTERRUPTED)
    352361        {
    353             VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient, GUEST_MSG_CANCEL, 0);
    354             int rc2 = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg.hdr));
     362            VBGL_HGCM_HDR_INIT(&Msg.Hdr, idClient, GUEST_MSG_CANCEL, 0);
     363            int rc2 = VbglR3HGCMCall(&Msg.Hdr, sizeof(Msg.Hdr));
    355364            AssertRC(rc2);
    356365        }
     366
     367        /*
     368         * If restored, update pidRestoreCheck.
     369         */
     370        if (rc == VERR_VM_RESTORED && pidRestoreCheck)
     371            *pidRestoreCheck = Msg.idMsg.u.value64;
    357372
    358373        *pidMsg       = UINT32_MAX - 1;
     
    363378    /*
    364379     * Fallback if host < v6.0.
     380     *
     381     * Note! The restore check isn't perfect. Would require checking afterwards
     382     *       and stash the result if we were restored during the call.  Too much
     383     *       hazzle for a downgrade scenario.
    365384     */
     385    if (pidRestoreCheck)
     386    {
     387        uint64_t idRestoreCur = *pidRestoreCheck;
     388        rc = VbglR3GetSessionId(&idRestoreCur);
     389        if (RT_SUCCESS(rc) && idRestoreCur != *pidRestoreCheck)
     390        {
     391            *pidRestoreCheck = idRestoreCur;
     392            return VERR_VM_RESTORED;
     393        }
     394    }
     395
    366396    rc = vbglR3GuestCtrlMsgWaitFor(idClient, pidMsg, pcParameters);
    367397    if (rc == VERR_TOO_MUCH_DATA)
  • trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControl.cpp

    r75824 r75853  
    251251    AssertReturn(pvScratchBuf, VERR_NO_MEMORY);
    252252
    253     VBGLR3GUESTCTRLCMDCTX ctxHost = { g_idControlSvcClient, 0 /*idContext*/, 2 /*uProtocol*/, 0  /*cParms*/ };
    254 
    255253    int rc = VINF_SUCCESS;      /* (shut up compiler warnings) */
    256254    int cRetrievalFailed = 0;   /* Number of failed message retrievals in a row. */
     
    258256    {
    259257        VGSvcVerbose(3, "GstCtrl: Waiting for host msg ...\n");
    260         uint32_t idMsg  = 0;
    261         uint32_t cParms = 0;
    262         rc = VbglR3GuestCtrlMsgPeekWait(g_idControlSvcClient, &idMsg, &cParms);
     258        VBGLR3GUESTCTRLCMDCTX ctxHost = { g_idControlSvcClient, 0 /*idContext*/, 2 /*uProtocol*/, 0  /*cParms*/ };
     259        uint32_t              idMsg  = 0;
     260        rc = VbglR3GuestCtrlMsgPeekWait(g_idControlSvcClient, &idMsg, &ctxHost.uNumParms, &g_idControlSession);
    263261        if (RT_SUCCESS(rc))
    264262        {
    265263            cRetrievalFailed = 0; /* Reset failed retrieval count. */
    266             VGSvcVerbose(4, "idMsg=%RU32 (%s) (%RU32 parms) retrieved\n", idMsg, GstCtrlHostFnName((eHostFn)idMsg), cParms);
    267 
    268             /*
    269              * Close all open guest sessions if the VM was restored (all context IDs,
    270              * sessions, etc. are now invalid).
    271              *
    272              * Note! This will suck performance wise if we get a lot of messages thru here.
    273              *       What about the service returning a HOST_MSG_RESTORED message?
    274              */
    275             uint64_t idNewSession = g_idControlSession;
    276             int rc2 = VbglR3GetSessionId(&idNewSession);
    277             if (   RT_SUCCESS(rc2)
    278                 && idNewSession != g_idControlSession)
    279             {
    280                 VGSvcVerbose(1, "The VM session ID changed (i.e. restored).\n");
    281                 g_idControlSession = idNewSession;
    282                 rc2 = VGSvcGstCtrlSessionClose(&g_Session);
    283                 AssertRC(rc2);
    284             }
     264            VGSvcVerbose(4, "idMsg=%RU32 (%s) (%RU32 parms) retrieved\n",
     265                         idMsg, GstCtrlHostFnName((eHostFn)idMsg), ctxHost.uNumParms);
    285266
    286267            /*
    287268             * Handle the host message.
    288269             */
    289             ctxHost.uNumParms = cParms;
    290270            switch (idMsg)
    291271            {
     
    308288                        rc = VbglR3GuestCtrlMsgSkip(g_idControlSvcClient, VERR_NOT_SUPPORTED, idMsg);
    309289                        VGSvcVerbose(1, "Skipped unexpected message idMsg=%RU32 (%s), cParms=%RU32 (rc=%Rrc)\n",
    310                                      idMsg, GstCtrlHostFnName((eHostFn)idMsg), cParms, rc);
     290                                     idMsg, GstCtrlHostFnName((eHostFn)idMsg), ctxHost.uNumParms, rc);
    311291                    }
    312292                    else
    313293                    {
    314294                        rc = VbglR3GuestCtrlMsgSkipOld(g_idControlSvcClient);
    315                         VGSvcVerbose(3, "Skipped idMsg=%RU32, cParms=%RU32, rc=%Rrc\n", idMsg, cParms, rc);
     295                        VGSvcVerbose(3, "Skipped idMsg=%RU32, cParms=%RU32, rc=%Rrc\n", idMsg, ctxHost.uNumParms, rc);
    316296                    }
    317297                    break;
     
    325305            RTThreadYield();
    326306        }
     307        /*
     308         * Handle restore notification from host.  All the context IDs (sessions,
     309         * files, proceses, etc) are invalidated by a VM restore and must be closed.
     310         */
     311        else if (rc == VERR_VM_RESTORED)
     312        {
     313            VGSvcVerbose(1, "The VM session ID changed (i.e. restored).\n");
     314            int rc2 = VGSvcGstCtrlSessionClose(&g_Session);
     315            AssertRC(rc2);
     316        }
    327317        else
    328318        {
     
    332322
    333323            /* Check for VM session change. */
     324            /** @todo  We don't need to check the host here.  */
    334325            uint64_t idNewSession = g_idControlSession;
    335326            int rc2 = VbglR3GetSessionId(&idNewSession);
  • trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControlSession.cpp

    r75824 r75853  
    15791579                    VGSvcVerbose(3, "Waiting for host msg ...\n");
    15801580                    uint32_t uMsg = 0;
    1581                     rc = VbglR3GuestCtrlMsgPeekWait(idClient, &uMsg, &CtxHost.uNumParms);
     1581                    rc = VbglR3GuestCtrlMsgPeekWait(idClient, &uMsg, &CtxHost.uNumParms, NULL);
    15821582                    if (RT_SUCCESS(rc))
    15831583                    {
Note: See TracChangeset for help on using the changeset viewer.

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