VirtualBox

Changeset 29965 in vbox for trunk


Ignore:
Timestamp:
Jun 1, 2010 6:41:10 PM (15 years ago)
Author:
vboxsync
Message:

Main: Make IConsole::teleport() fail with the same message as the target when there are configuration errors.

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

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/ConsoleImpl.cpp

    r29957 r29965  
    212212                  Progress *aProgress)
    213213        : VMProgressTask(aConsole, aProgress, false /* aUsesVMPtr */),
    214           mSetVMErrorCallback(NULL),
    215214          mConfigConstructor(NULL),
    216215          mStartPaused(false),
     
    218217    {}
    219218
    220     PFNVMATERROR mSetVMErrorCallback;
    221219    PFNCFGMCONSTRUCTOR mConfigConstructor;
    222220    Utf8Str mSavedStateFile;
     
    52715269    ComAssertComRCRetRC(task->rc());
    52725270
    5273     task->mSetVMErrorCallback = setVMErrorCallback;
    52745271    task->mConfigConstructor = configConstructor;
    52755272    task->mSharedFolders = sharedFolders;
     
    68716868
    68726869/**
    6873  * VM error callback function. Called by the various VM components.
    6874  *
    6875  * @param   pVM         VM handle. Can be NULL if an error occurred before
    6876  *                      successfully creating a VM.
    6877  * @param   pvUser      Pointer to the VMProgressTask structure.
    6878  * @param   rc          VBox status code.
    6879  * @param   pszFormat   Printf-like error message.
    6880  * @param   args        Various number of arguments for the error message.
    6881  *
    6882  * @thread EMT, VMPowerUp...
    6883  *
    6884  * @note The VMProgressTask structure modified by this callback is not thread
    6885  *       safe.
     6870 * @copydoc FNVMATERROR
     6871 *
     6872 * @remarks Might be some tiny serialization concerns with access to the string
     6873 *          object here...
    68866874 */
    6887 /* static */ DECLCALLBACK(void)
    6888 Console::setVMErrorCallback(PVM pVM, void *pvUser, int rc, RT_SRC_POS_DECL,
    6889                             const char *pszFormat, va_list args)
    6890 {
    6891     VMProgressTask *task = static_cast<VMProgressTask *>(pvUser);
    6892     AssertReturnVoid(task);
    6893 
    6894     /* we ignore RT_SRC_POS_DECL arguments to avoid confusion of end-users */
     6875/*static*/ DECLCALLBACK(void)
     6876Console::genericVMSetErrorCallback(PVM pVM, void *pvUser, int rc, RT_SRC_POS_DECL,
     6877                                   const char *pszErrorFmt, va_list va)
     6878{
     6879    Utf8Str *pErrorText = (Utf8Str *)pvUser;
     6880    AssertPtr(pErrorText);
     6881
     6882    /* We ignore RT_SRC_POS_DECL arguments to avoid confusion of end-users. */
    68956883    va_list va2;
    6896     va_copy(va2, args); /* Have to make a copy here or GCC will break. */
    6897 
    6898     /* append to the existing error message if any */
    6899     if (task->mErrorMsg.length())
    6900         task->mErrorMsg = Utf8StrFmt("%s.\n%N (%Rrc)", task->mErrorMsg.raw(),
    6901                                      pszFormat, &va2, rc, rc);
     6884    va_copy(va2, va);
     6885
     6886    /* Append to any the existing error message. */
     6887    if (pErrorText->length())
     6888        *pErrorText = Utf8StrFmt("%s.\n%N (%Rrc)", pErrorText->c_str(),
     6889                                 pszErrorFmt, &va2, rc, rc);
    69026890    else
    6903         task->mErrorMsg = Utf8StrFmt("%N (%Rrc)",
    6904                                      pszFormat, &va2, rc, rc);
    6905 
    6906     va_end (va2);
     6891        *pErrorText = Utf8StrFmt("%N (%Rrc)", pszErrorFmt, &va2, rc, rc);
     6892
     6893    va_end(va2);
    69076894}
    69086895
     
    73027289        alock.leave();
    73037290
    7304         vrc = VMR3Create(cCpus, task->mSetVMErrorCallback, task.get(),
     7291        vrc = VMR3Create(cCpus, Console::genericVMSetErrorCallback, &task->mErrorMsg,
    73057292                         task->mConfigConstructor, static_cast<Console *>(console),
    73067293                         &pVM);
     
    74517438                 */
    74527439                alock.leave();
    7453                 VMR3AtErrorDeregister(pVM, task->mSetVMErrorCallback, task.get());
     7440                VMR3AtErrorDeregister(pVM, Console::genericVMSetErrorCallback, &task->mErrorMsg);
    74547441                /** @todo register another VMSetError callback? */
    74557442                alock.enter();
  • trunk/src/VBox/Main/ConsoleImplTeleporter.cpp

    r29957 r29965  
    121121    bool                        mfLockedMedia;
    122122    int                         mRc;
     123    Utf8Str                     mErrorText;
    123124
    124125    TeleporterStateTrg(Console *pConsole, PVM pVM, Progress *pProgress,
     
    132133        , mfLockedMedia(false)
    133134        , mRc(VINF_SUCCESS)
     135        , mErrorText()
    134136    {
    135137    }
     
    219221HRESULT
    220222Console::teleporterSrcReadACK(TeleporterStateSrc *pState, const char *pszWhich,
    221                              const char *pszNAckMsg /*= NULL*/)
    222 {
    223     char szMsg[128];
     223                              const char *pszNAckMsg /*= NULL*/)
     224{
     225    char szMsg[256];
    224226    int vrc = teleporterTcpReadLine(pState, szMsg, sizeof(szMsg));
    225227    if (RT_FAILURE(vrc))
    226228        return setError(E_FAIL, tr("Failed reading ACK(%s): %Rrc"), pszWhich, vrc);
    227     if (strcmp(szMsg, "ACK"))
    228     {
    229         if (!strncmp(szMsg, "NACK=", sizeof("NACK=") - 1))
    230         {
    231             int32_t vrc2;
    232             vrc = RTStrToInt32Full(&szMsg[sizeof("NACK=") - 1], 10, &vrc2);
    233             if (vrc == VINF_SUCCESS)
    234             {
    235                 if (pszNAckMsg)
    236                 {
    237                     LogRel(("Teleporter: %s: NACK=%Rrc (%d)\n", pszWhich, vrc2, vrc2));
    238                     return setError(E_FAIL, pszNAckMsg);
    239                 }
    240                 return setError(E_FAIL, "NACK(%s) - %Rrc (%d)", pszWhich, vrc2, vrc2);
    241             }
    242         }
    243         return setError(E_FAIL, tr("%s: Expected ACK or NACK, got '%s'"), pszWhich, szMsg);
    244     }
    245     return S_OK;
     229
     230    if (!strcmp(szMsg, "ACK"))
     231        return S_OK;
     232
     233    if (!strncmp(szMsg, "NACK=", sizeof("NACK=") - 1))
     234    {
     235        char *pszMsgText = strchr(szMsg, ';');
     236        if (pszMsgText)
     237            *pszMsgText++ = '\0';
     238
     239        int32_t vrc2;
     240        vrc = RTStrToInt32Full(&szMsg[sizeof("NACK=") - 1], 10, &vrc2);
     241        if (vrc == VINF_SUCCESS)
     242        {
     243            /*
     244             * Well formed NACK, transform it into an error.
     245             */
     246            if (pszNAckMsg)
     247            {
     248                LogRel(("Teleporter: %s: NACK=%Rrc (%d)\n", pszWhich, vrc2, vrc2));
     249                return setError(E_FAIL, pszNAckMsg);
     250            }
     251
     252            if (pszMsgText)
     253            {
     254                pszMsgText = RTStrStrip(pszMsgText);
     255                for (size_t off = 0; pszMsgText[off]; off++)
     256                    if (pszMsgText[off] == '\r')
     257                        pszMsgText[off] = '\n';
     258
     259                LogRel(("Teleporter: %s: NACK=%Rrc (%d) - '%s'\n", pszWhich, vrc2, vrc2, pszMsgText));
     260                if (strlen(pszMsgText) > 4)
     261                    return setError(E_FAIL, "%s", pszMsgText);
     262                return setError(E_FAIL, "NACK(%s) - %Rrc (%d) '%s'", pszWhich, vrc2, vrc2, pszMsgText);
     263            }
     264
     265            return setError(E_FAIL, "NACK(%s) - %Rrc (%d)", pszWhich, vrc2, vrc2);
     266        }
     267
     268        if (pszMsgText)
     269            pszMsgText[-1] = ';';
     270    }
     271    return setError(E_FAIL, tr("%s: Expected ACK or NACK, got '%s'"), pszWhich, szMsg);
    246272}
    247273
     
    672698    RTSocketRelease(pState->mhSocket);
    673699    if (RT_FAILURE(vrc))
     700    {
     701        if (   vrc == VERR_SSM_CANCELLED
     702            && RT_SUCCESS(RTTcpSelectOne(pState->mhSocket, 1)))
     703        {
     704            hrc = teleporterSrcReadACK(pState, "load-complete");
     705            if (FAILED(hrc))
     706                return hrc;
     707        }
    674708        return setError(E_FAIL, tr("VMR3Teleport -> %Rrc"), vrc);
     709    }
    675710
    676711    hrc = teleporterSrcReadACK(pState, "load-complete");
     
    11791214
    11801215
    1181 static int teleporterTcpWriteNACK(TeleporterStateTrg *pState, int32_t rc2)
     1216static int teleporterTcpWriteNACK(TeleporterStateTrg *pState, int32_t rc2, const char *pszMsgText = NULL)
    11821217{
    11831218    /*
     
    11871222    teleporterTrgUnlockMedia(pState);
    11881223
    1189     char    szMsg[64];
    1190     size_t  cch = RTStrPrintf(szMsg, sizeof(szMsg), "NACK=%d\n", rc2);
     1224    char    szMsg[256];
     1225    size_t  cch;
     1226    if (pszMsgText && *pszMsgText)
     1227    {
     1228        cch = RTStrPrintf(szMsg, sizeof(szMsg), "NACK=%d;%s\n", rc2, pszMsgText);
     1229        for (size_t off = 6; off + 1 < cch; off++)
     1230            if (szMsg[off] == '\n')
     1231                szMsg[off] = '\r';
     1232    }
     1233    else
     1234        cch = RTStrPrintf(szMsg, sizeof(szMsg), "NACK=%d\n", rc2);
    11911235    int rc = RTTcpWrite(pState->mhSocket, szMsg, cch);
    11921236    if (RT_FAILURE(rc))
     
    12881332                break;
    12891333
     1334            int vrc2 = VMR3AtErrorRegister(pState->mpVM, Console::genericVMSetErrorCallback, &pState->mErrorText); AssertRC(vrc2);
    12901335            RTSocketRetain(pState->mhSocket); /* For concurrent access by I/O thread and EMT. */
    12911336            pState->moffStream = 0;
     1337
    12921338            void *pvUser2 = static_cast<void *>(static_cast<TeleporterState *>(pState));
    12931339            vrc = VMR3LoadFromStream(pState->mpVM, &g_teleporterTcpOps, pvUser2,
    12941340                                     teleporterProgressCallback, pvUser2);
     1341
    12951342            RTSocketRelease(pState->mhSocket);
     1343            vrc2 = VMR3AtErrorDeregister(pState->mpVM, Console::genericVMSetErrorCallback, &pState->mErrorText); AssertRC(vrc2);
     1344
    12961345            if (RT_FAILURE(vrc))
    12971346            {
    12981347                LogRel(("Teleporter: VMR3LoadFromStream -> %Rrc\n", vrc));
    1299                 teleporterTcpWriteNACK(pState, vrc);
     1348                teleporterTcpWriteNACK(pState, vrc, pState->mErrorText.c_str());
    13001349                break;
    13011350            }
  • trunk/src/VBox/Main/include/ConsoleImpl.h

    r29957 r29965  
    519519    static DECLCALLBACK(int)    stateProgressCallback(PVM pVM, unsigned uPercent, void *pvUser);
    520520
    521     static DECLCALLBACK(void)   setVMErrorCallback(PVM pVM, void *pvUser, int rc, RT_SRC_POS_DECL,
    522                                                    const char *pszFormat, va_list args);
     521    static DECLCALLBACK(void)   genericVMSetErrorCallback(PVM pVM, void *pvUser, int rc, RT_SRC_POS_DECL,
     522                                                          const char *pszErrorFmt, va_list va);
    523523
    524524    static DECLCALLBACK(void) setVMRuntimeErrorCallbackF(PVM pVM, void *pvUser, uint32_t fFatal,
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