VirtualBox

Changeset 98614 in vbox


Ignore:
Timestamp:
Feb 17, 2023 1:09:38 AM (2 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
155906
Message:

Main/GuestProcess: Simplified the GuestProcessToolbox::run stuff to sort out the issue VERR_IPE_UNINITIALIZED_STATUS introduced around r155802+. Also decoded the meaning of the GuestCtrlStreamObjects parameters and tried to make that easier to understand for the uninitiated. bugref:9783

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

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/include/GuestProcessImpl.h

    r98526 r98614  
    269269
    270270    /** Wrapped @name Static run methods.
    271      * @{ */
    272     static int run(GuestSession *pGuestSession, const GuestProcessStartupInfo &startupInfo, int *pvrcGuest);
    273 
    274     static int runErrorInfo(GuestSession *pGuestSession, const GuestProcessStartupInfo &startupInfo, GuestProcessToolErrorInfo &errorInfo);
    275 
    276     static int runEx(GuestSession *pGuestSession, const GuestProcessStartupInfo &startupInfo,
    277                      GuestCtrlStreamObjects *pStrmOutObjects, uint32_t cStrmOutObjects, int *pvrcGuest);
    278 
    279     static int runExErrorInfo(GuestSession *pGuestSession, const GuestProcessStartupInfo &startupInfo,
    280                               GuestCtrlStreamObjects *pStrmOutObjects, uint32_t cStrmOutObjects, GuestProcessToolErrorInfo &errorInfo);
     271     * @note Do not call anything 'run' here, it's way too common.
     272     * @{ */
     273    static int runTool(GuestSession *pGuestSession, const GuestProcessStartupInfo &startupInfo, int *pvrcGuest,
     274                       GuestCtrlStreamObjects *pLstStdOutObjPairs = NULL, uint32_t cStdOutObjectsToRead = 1);
     275
     276    static int runToolWithErrorInfo(GuestSession *pGuestSession, const GuestProcessStartupInfo &startupInfo,
     277                                    GuestProcessToolErrorInfo &errorInfo,
     278                                    GuestCtrlStreamObjects *pLstStdOutObjPairs = NULL, uint32_t cStdOutObjectsToRead = 1);
    281279    /** @}  */
    282280
  • trunk/src/VBox/Main/src-client/GuestDirectoryImpl.cpp

    r98528 r98614  
    619619        RT_NOREF(objData);
    620620        vrc = VERR_NOT_SUPPORTED;
    621 #else  /* VBOX_WITH_GSTCTL_TOOLBOX_SUPPORT */
     621#else
    622622        vrc = i_readInternalViaToolbox(objData, pvrcGuest);
    623 #endif /* VBOX_WITH_GSTCTL_TOOLBOX_SUPPORT */
     623#endif
    624624#ifdef VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS
    625625    }
  • trunk/src/VBox/Main/src-client/GuestProcessImpl.cpp

    r98608 r98614  
    24172417
    24182418/**
    2419  * Static helper function to start and wait for a certain toolbox tool.
    2420  *
    2421  * This function most likely is the one you want to use in the first place if you
    2422  * want to just use a toolbox tool and wait for its result. See runEx() if you also
    2423  * needs its output.
    2424  *
    2425  * @return  VBox status code.
     2419 * Static helper function to start and wait for output of a certain toolbox tool.
     2420 *
     2421 * The optional @a pLstStdOutObjects argument enables the caller to retrieve
     2422 * so-called parsable guest stream objects containing additional information on
     2423 * a key value pair basis.  Those objects are emitted on the guest side by the
     2424 * tool to convey retrieve additional information, like names in a directory or
     2425 * file statistics, to the host.
     2426 *
     2427 * @return  IPRT status code.
    24262428 * @param   pGuestSession           Guest control session to use for starting the toolbox tool in.
    24272429 * @param   startupInfo             Startup information about the toolbox tool.
    2428  * @param   pvrcGuest               Where to store the toolbox tool's specific error code in case
    2429  *                                  VERR_GSTCTL_GUEST_ERROR is returned.
     2430 * @param   pvrcGuest               Error code returned from the guest side if VERR_GSTCTL_GUEST_ERROR is returned.
     2431 * @param   pLstStdOutObjects       Pointer to vector to receive the stdout
     2432 *                                  objects.  Optional.
     2433 * @param   cStdOutObjectsToRead    Number of parsable guest stream objects to
     2434 *                                  try receive and parse.  Ignored when
     2435 *                                  pLstStdOutObjects is NULL.  Optional.
    24302436 */
    24312437/* static */
    2432 int GuestProcessToolbox::run(GuestSession                  *pGuestSession,
    2433                              GuestProcessStartupInfo const &startupInfo,
    2434                              int                           *pvrcGuest /* = NULL */)
     2438int GuestProcessToolbox::runTool(GuestSession                  *pGuestSession,
     2439                                 GuestProcessStartupInfo const &startupInfo,
     2440                                 int                           *pvrcGuest,
     2441                                 GuestCtrlStreamObjects        *pLstStdOutObjects /* = NULL */,
     2442                                 uint32_t                       cStdOutObjectsToRead /* = 1 */)
    24352443{
    24362444    GuestProcessToolErrorInfo errorInfo = { VERR_IPE_UNINITIALIZED_STATUS, INT32_MAX };
    2437     int vrc = runErrorInfo(pGuestSession, startupInfo, errorInfo);
     2445    int vrc = GuestProcessToolbox::runToolWithErrorInfo(pGuestSession, startupInfo,
     2446                                                        errorInfo, pLstStdOutObjects, cStdOutObjectsToRead);
    24382447    if (RT_SUCCESS(vrc))
    24392448    {
    2440 /** @todo r=bird: Seems like this is duplicated in the runErrInfo or
    2441  *        something, because it returns with VERR_GSTCTL_GUEST_ERROR.
    2442  *        Temporary fix is to always set pvrcGuest before returning. */
    2443         /* Make sure to check the error information we got from the guest tool. */
    2444         if (GuestProcess::i_isGuestError(errorInfo.vrcGuest))
    2445         {
    2446             if (errorInfo.vrcGuest == VERR_GSTCTL_PROCESS_EXIT_CODE) /* Translate exit code to a meaningful error code. */
    2447                 errorInfo.vrcGuest = GuestProcessToolbox::exitCodeToRc(startupInfo, errorInfo.iExitCode);
     2449        /* Translate exit statuses to VBox statuses according to the guest tool: */
     2450        if (errorInfo.vrcGuest == VERR_GSTCTL_PROCESS_EXIT_CODE)
     2451        {
     2452            errorInfo.vrcGuest = GuestProcessToolbox::exitCodeToRc(startupInfo, errorInfo.iExitCode);
    24482453            vrc = VERR_GSTCTL_GUEST_ERROR;
    24492454        }
    2450     }
    2451 
    2452     /* See above. */
    2453     if (pvrcGuest)
    2454         *pvrcGuest = errorInfo.vrcGuest;
    2455 
     2455        /* In case of something else that may be relevant: */
     2456        else if (errorInfo.vrcGuest == VERR_GSTCTL_PROCESS_WRONG_STATE /* possible getTerminationStatus result, see below */)
     2457            vrc = VERR_GSTCTL_GUEST_ERROR;
     2458        else
     2459            AssertMsg(errorInfo.vrcGuest == VERR_IPE_UNINITIALIZED_STATUS || errorInfo.vrcGuest == VINF_SUCCESS,
     2460                      ("vrcGuest=%Rrc iExitCode=%d vrc=%Rrc\n", errorInfo.vrcGuest, errorInfo.iExitCode, vrc));
     2461    }
     2462
     2463    *pvrcGuest = errorInfo.vrcGuest;
    24562464    LogFlowFunc(("returns %Rrc - vrcGuest=%Rrc iExitCode=%d\n", vrc, errorInfo.vrcGuest, errorInfo.iExitCode));
    24572465    return vrc;
     
    24592467
    24602468/**
    2461  * Static helper function to start and wait for a certain toolbox tool, returning
    2462  * extended error information from the guest.
     2469 * Bare-bone version of runTool that doesn't translate exit codes to statuses.
     2470 *
     2471 * It's currently not used by anyone other than runTool().
    24632472 *
    24642473 * @return  VBox status code.
     
    24662475 * @param   startupInfo             Startup information about the toolbox tool.
    24672476 * @param   errorInfo               Error information returned for error handling.
     2477 * @param   pLstStdOutObjects       Pointer to vector to receive the stdout
     2478 *                                  objects.  Optional.
     2479 * @param   cStdOutObjectsToRead    Number of parsable guest stream objects to
     2480 *                                  try receive and parse.  Ignored when
     2481 *                                  pLstStdOutObjects is NULL.  Optional.
     2482 *
     2483 * @note    This will not do call exitCodeToRc, for that use runTool().
    24682484 */
    24692485/* static */
    2470 int GuestProcessToolbox::runErrorInfo(GuestSession                 *pGuestSession,
    2471                                       GuestProcessStartupInfo const &startupInfo,
    2472                                       GuestProcessToolErrorInfo     &errorInfo)
    2473 {
    2474     return runExErrorInfo(pGuestSession, startupInfo, NULL /* paStrmOutObjects */, 0 /* cStrmOutObjects */, errorInfo);
    2475 }
    2476 
    2477 /**
    2478  * Static helper function to start and wait for output of a certain toolbox tool.
    2479  *
    2480  * @return  IPRT status code.
    2481  * @param   pGuestSession           Guest control session to use for starting the toolbox tool in.
    2482  * @param   startupInfo             Startup information about the toolbox tool.
    2483  * @param   paStrmOutObjects        Pointer to stream objects array to use for retrieving the output of the toolbox tool.
    2484  *                                  Optional.
    2485  * @param   cStrmOutObjects         Number of stream objects passed in. Optional.
    2486  * @param   pvrcGuest               Error code returned from the guest side if VERR_GSTCTL_GUEST_ERROR is returned. Optional.
    2487  */
    2488 /* static */
    2489 int GuestProcessToolbox::runEx(GuestSession                  *pGuestSession,
    2490                                GuestProcessStartupInfo const &startupInfo,
    2491                                GuestCtrlStreamObjects        *paStrmOutObjects,
    2492                                uint32_t                       cStrmOutObjects,
    2493                                int                           *pvrcGuest /* = NULL */)
    2494 {
    2495     int vrcGuest = VERR_IPE_UNINITIALIZED_STATUS;
    2496 
    2497     GuestProcessToolErrorInfo errorInfo = { VERR_IPE_UNINITIALIZED_STATUS, INT32_MAX };
    2498     int vrc = GuestProcessToolbox::runExErrorInfo(pGuestSession, startupInfo, paStrmOutObjects, cStrmOutObjects, errorInfo);
    2499     if (RT_SUCCESS(vrc))
    2500     {
    2501         /* Make sure to check the error information we got from the guest tool. */
    2502         if (GuestProcess::i_isGuestError(errorInfo.vrcGuest))
    2503         {
    2504             if (errorInfo.vrcGuest == VERR_GSTCTL_PROCESS_EXIT_CODE) /* Translate exit code to a meaningful error code. */
    2505                 vrcGuest = GuestProcessToolbox::exitCodeToRc(startupInfo, errorInfo.iExitCode);
    2506             else /* At least return something. */
    2507                 vrcGuest = errorInfo.vrcGuest;
    2508 
    2509             if (pvrcGuest)
    2510                 *pvrcGuest = vrcGuest;
    2511 
    2512             vrc = VERR_GSTCTL_GUEST_ERROR;
    2513         }
    2514     }
    2515 
    2516     LogFlowFunc(("returns %Rrc - vrcGuest=%Rrc iExitCode=%d\n", vrc, errorInfo.vrcGuest, errorInfo.iExitCode));
    2517     return vrc;
    2518 }
    2519 
    2520 /**
    2521  * Static helper function to start and wait for output of a certain toolbox tool.
    2522  *
    2523  * This is the extended version, which addds the possibility of retrieving parsable so-called guest stream
    2524  * objects. Those objects are issued on the guest side as part of VBoxService's toolbox tools (think of a BusyBox-like approach)
    2525  * on stdout and can be used on the host side to retrieve more information about the actual command issued on the guest side.
    2526  *
    2527  * @return  VBox status code.
    2528  * @param   pGuestSession           Guest control session to use for starting the toolbox tool in.
    2529  * @param   startupInfo             Startup information about the toolbox tool.
    2530  * @param   paStrmOutObjects        Pointer to stream objects array to use for retrieving the output of the toolbox tool.
    2531  *                                  Optional.
    2532  * @param   cStrmOutObjects         Number of stream objects passed in. Optional.
    2533  * @param   errorInfo               Error information returned for error handling.
    2534  */
    2535 /* static */
    2536 int GuestProcessToolbox::runExErrorInfo(GuestSession                  *pGuestSession,
    2537                                         GuestProcessStartupInfo const &startupInfo,
    2538                                         GuestCtrlStreamObjects        *paStrmOutObjects,
    2539                                         uint32_t                       cStrmOutObjects,
    2540                                         GuestProcessToolErrorInfo     &errorInfo)
    2541 {
    2542     AssertPtrReturn(pGuestSession, VERR_INVALID_POINTER);
    2543     /* paStrmOutObjects is optional. */
    2544 
    2545     /** @todo Check if this is a valid toolbox. */
    2546 
     2486int GuestProcessToolbox::runToolWithErrorInfo(GuestSession                  *pGuestSession,
     2487                                              GuestProcessStartupInfo const &startupInfo,
     2488                                              GuestProcessToolErrorInfo     &errorInfo,
     2489                                              GuestCtrlStreamObjects        *pLstStdOutObjects /* = NULL */,
     2490                                              uint32_t                       cStdOutObjectsToRead /* = 1 */)
     2491{
    25472492    GuestProcessToolbox procTool;
    2548     int vrc = procTool.init(pGuestSession, startupInfo, false /* Async */, &errorInfo.vrcGuest);
    2549     if (RT_SUCCESS(vrc))
    2550     {
    2551         while (cStrmOutObjects--)
    2552         {
     2493    int vrc = procTool.init(pGuestSession, startupInfo, false /* fAsync */, &errorInfo.vrcGuest);
     2494    if (pLstStdOutObjects)
     2495        while (RT_SUCCESS(vrc) && cStdOutObjectsToRead-- > 0)
    25532496            try
    25542497            {
    25552498                GuestToolboxStreamBlock strmBlk;
    2556                 vrc = procTool.waitEx(paStrmOutObjects
    2557                                       ? GUESTPROCESSTOOL_WAIT_FLAG_STDOUT_BLOCK
    2558                                       : GUESTPROCESSTOOL_WAIT_FLAG_NONE,
    2559                                       &strmBlk, &errorInfo.vrcGuest);
    2560                 if (paStrmOutObjects)
    2561                     paStrmOutObjects->push_back(strmBlk);
     2499                vrc = procTool.waitEx(GUESTPROCESSTOOL_WAIT_FLAG_STDOUT_BLOCK, &strmBlk, &errorInfo.vrcGuest);
     2500                pLstStdOutObjects->push_back(strmBlk);
    25622501            }
    25632502            catch (std::bad_alloc &)
     
    25652504                vrc = VERR_NO_MEMORY;
    25662505            }
    2567 
    2568             if (RT_FAILURE(vrc))
    2569                 break;
    2570         }
    2571     }
    2572 
    25732506    if (RT_SUCCESS(vrc))
    25742507    {
     
    25872520 * Reports if the tool has been run correctly.
    25882521 *
    2589  * @return  Will return VERR_GSTCTL_PROCESS_EXIT_CODE if the tool process returned an exit code <> 0,
    2590  *          VERR_GSTCTL_PROCESS_WRONG_STATE if the tool process is in a wrong state (e.g. still running),
    2591  *          or VINF_SUCCESS otherwise.
     2522 * @retval  VINF_SUCCESS if the process has stopped and the exit code is zero.
     2523 * @retval  VERR_GSTCTL_PROCESS_EXIT_CODE if the exit code is _not_ zero.
     2524 * @retval  VERR_GSTCTL_PROCESS_WRONG_STATE if still running.
    25922525 *
    25932526 * @param   piExitCode      Exit code of the tool. Optional.
     
    25962529{
    25972530    Assert(!pProcess.isNull());
    2598     /* pExitCode is optional. */
     2531    AssertPtrNull(piExitCode);
    25992532
    26002533    int vrc;
     
    26082541            *piExitCode = iExitCode;
    26092542
    2610         vrc = iExitCode != 0 ? VERR_GSTCTL_PROCESS_EXIT_CODE : VINF_SUCCESS;
     2543        vrc = iExitCode == 0 ? VINF_SUCCESS : VERR_GSTCTL_PROCESS_EXIT_CODE;
    26112544    }
    26122545    else
     2546    {
     2547        if (piExitCode)
     2548            *piExitCode = -1;
    26132549        vrc = VERR_GSTCTL_PROCESS_WRONG_STATE;
     2550    }
    26142551
    26152552    LogFlowFuncLeaveRC(vrc);
     
    26682605    bool fDone = false;
    26692606
    2670     BYTE byBuf[_64K];
     2607    BYTE abBuf[_64K];
    26712608    uint32_t cbRead;
    26722609
     
    26902627     * Returns the remaining time (in ms).
    26912628     */
    2692 #define GET_REMAINING_TIME                                     \
    2693       uTimeoutMS == RT_INDEFINITE_WAIT                         \
    2694     ? RT_INDEFINITE_WAIT : uTimeoutMS - (uint32_t)u64ElapsedMS \
     2629#define GET_REMAINING_TIME (uTimeoutMS == RT_INDEFINITE_WAIT ? RT_INDEFINITE_WAIT : uTimeoutMS - (uint32_t)u64ElapsedMS)
    26952630
    26962631    ProcessWaitResult_T waitRes = ProcessWaitResult_None;
     
    27582693
    27592694            cbRead = 0;
    2760             vrc = pProcess->i_readData(GUEST_PROC_OUT_H_STDOUT, sizeof(byBuf),
     2695            vrc = pProcess->i_readData(GUEST_PROC_OUT_H_STDOUT, sizeof(abBuf),
    27612696                                       GET_REMAINING_TIME,
    2762                                        byBuf, sizeof(byBuf),
     2697                                       abBuf, sizeof(abBuf),
    27632698                                       &cbRead, &vrcGuest);
    27642699            if (   RT_FAILURE(vrc)
     
    27692704            {
    27702705                LogFlowThisFunc(("Received %RU32 bytes from stdout\n", cbRead));
    2771                 vrc = mStdOut.AddData(byBuf, cbRead);
     2706                vrc = mStdOut.AddData(abBuf, cbRead);
    27722707
    27732708                if (   RT_SUCCESS(vrc)
     
    27922727
    27932728            cbRead = 0;
    2794             vrc = pProcess->i_readData(GUEST_PROC_OUT_H_STDERR, sizeof(byBuf),
     2729            vrc = pProcess->i_readData(GUEST_PROC_OUT_H_STDERR, sizeof(abBuf),
    27952730                                       GET_REMAINING_TIME,
    2796                                        byBuf, sizeof(byBuf),
     2731                                       abBuf, sizeof(abBuf),
    27972732                                       &cbRead, &vrcGuest);
    27982733            if (   RT_FAILURE(vrc)
     
    28032738            {
    28042739                LogFlowThisFunc(("Received %RU32 bytes from stderr\n", cbRead));
    2805                 vrc = mStdErr.AddData(byBuf, cbRead);
     2740                vrc = mStdErr.AddData(abBuf, cbRead);
    28062741            }
    28072742
  • trunk/src/VBox/Main/src-client/GuestSessionImpl.cpp

    r98610 r98614  
    10291029
    10301030        if (RT_SUCCESS(vrc))
    1031             vrc = GuestProcessToolbox::run(this, procInfo, pvrcGuest);
     1031            vrc = GuestProcessToolbox::runTool(this, procInfo, pvrcGuest);
    10321032#endif /* VBOX_WITH_GSTCTL_TOOLBOX_SUPPORT */
    10331033    }
     
    13031303
    13041304        GuestCtrlStreamObjects stdOut;
    1305         vrc = GuestProcessToolbox::runEx(this, procInfo, &stdOut, 1 /* cStrmOutObjects */, &vrcGuest);
     1305        vrc = GuestProcessToolbox::runTool(this, procInfo, &vrcGuest, &stdOut);
    13061306        if (!GuestProcess::i_isGuestError(vrc))
    13071307        {
     
    17341734
    17351735        GuestCtrlStreamObjects stdOut;
    1736         vrc = GuestProcessToolbox::runEx(this, procInfo, &stdOut, 1 /* cStrmOutObjects */, &vrcGuest);
    1737         if (GuestProcess::i_isGuestError(vrc))
     1736        vrc = GuestProcessToolbox::runTool(this, procInfo, &vrcGuest, &stdOut);
     1737        if (!GuestProcess::i_isGuestError(vrc))
    17381738        {
    17391739            if (!stdOut.empty())
     
    20402040        try
    20412041        {
    2042             procInfo.mExecutable = Utf8Str(VBOXSERVICE_TOOL_STAT);
     2042            procInfo.mExecutable = VBOXSERVICE_TOOL_STAT;
    20432043            procInfo.mArguments.push_back(procInfo.mExecutable); /* Set argv0. */
    20442044            procInfo.mArguments.push_back(Utf8Str("--machinereadable"));
     
    20552055
    20562056        GuestCtrlStreamObjects stdOut;
    2057         vrc = GuestProcessToolbox::runEx(this, procInfo, &stdOut, 1 /* cStrmOutObjects */, &vrcGuest);
     2057        vrc = GuestProcessToolbox::runTool(this, procInfo, &vrcGuest, &stdOut);
    20582058        if (!GuestProcess::i_isGuestError(vrc))
    20592059        {
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