VirtualBox

Changeset 78361 in vbox for trunk/src


Ignore:
Timestamp:
May 1, 2019 4:12:47 AM (6 years ago)
Author:
vboxsync
Message:

FsPerf: More on the slave mode for testing host<->guest interaction. bugref:9172

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/ValidationKit/utils/fs/FsPerf.cpp

    r78360 r78361  
    9393 * It greatly exceeds the RTPATH_MAX so we can push the limits on windows.  */
    9494#define FSPERF_MAX_PATH         (_32K)
     95
     96/** EOF marker character used by the master/slave comms.  */
     97#define FSPERF_EOF              0x1a
     98/** EOF marker character used by the master/slave comms, string version.  */
     99#define FSPERF_EOF_STR          "\x1a"
    95100
    96101/** @def FSPERF_TEST_SENDFILE
     
    321326    kCmdOpt_Copy,
    322327    kCmdOpt_NoCopy,
     328    kCmdOpt_Remote,
     329    kCmdOpt_NoRemote,
    323330
    324331    kCmdOpt_ShowDuration,
     
    414421    { "--copy",             kCmdOpt_Copy,           RTGETOPT_REQ_NOTHING },
    415422    { "--no-copy",          kCmdOpt_NoCopy,         RTGETOPT_REQ_NOTHING },
     423    { "--remote",           kCmdOpt_Remote,         RTGETOPT_REQ_NOTHING },
     424    { "--no-remote",        kCmdOpt_NoRemote,       RTGETOPT_REQ_NOTHING },
    416425
    417426    { "--show-duration",        kCmdOpt_ShowDuration,       RTGETOPT_REQ_NOTHING },
     
    471480static bool         g_fMMap      = true;
    472481static bool         g_fCopy      = true;
     482static bool         g_fRemote    = true;
    473483/** @} */
    474484
     
    652662
    653663
    654 #if 0 // currently unused
    655664/**
    656665 * Construct a path relative to the comms sub-directory.
     
    667676    return &g_szCommsSubDir[0];
    668677}
    669 #endif
    670678
    671679
     
    707715
    708716
    709 #if 0 // currently unused
    710717/**
    711718 * Creates a file under g_szCommsDir with the given content, then renames it
     
    735742    return rc;
    736743}
    737 #endif
    738744
    739745
     
    813819        if (   RT_SUCCESS(rc)
    814820            && (   cbUsed == 0
    815                 || pszBuf[cbUsed - 1] != 0x1a))
     821                || pszBuf[cbUsed - 1] != FSPERF_EOF))
    816822            rc = VERR_TRY_AGAIN;
    817823
     
    853859}
    854860
     861
     862/** The comms master sequence number.   */
     863static uint32_t g_iSeqNoMaster = 0;
     864
     865
     866/**
     867 * Sends a script to the remote comms slave.
     868 *
     869 * @returns IPRT status code giving the scripts execution status.
     870 * @param   pszScript           The script.
     871 */
     872static int FsPerfCommsSend(const char *pszScript)
     873{
     874    /*
     875     * Make sure the script is correctly terminated with an EOF control character.
     876     */
     877    size_t const cchScript = strlen(pszScript);
     878    AssertReturn(cchScript > 0 && pszScript[cchScript - 1] == FSPERF_EOF, VERR_INVALID_PARAMETER);
     879
     880    /*
     881     * Make sure the comms slave is running.
     882     */
     883    if (!RTFileExists(InCommsDir(RT_STR_TUPLE("slave.pid"))))
     884        return VERR_PIPE_NOT_CONNECTED;
     885
     886    /*
     887     * Format all the names we might want to check for.
     888     */
     889    char         szSendNm[32];
     890    size_t const cchSendNm = RTStrPrintf(szSendNm, sizeof(szSendNm), "%u-order.send", g_iSeqNoMaster);
     891
     892    char         szAckNm[64];
     893    size_t const cchAckNm  = RTStrPrintf(szAckNm, sizeof(szAckNm),   "%u-order.ack", g_iSeqNoMaster);
     894
     895    /*
     896     * Produce the script file and submit it.
     897     */
     898    int rc = FsPerfCommsWriteFileAndRename(szSendNm, cchSendNm, pszScript, cchScript);
     899    if (RT_SUCCESS(rc))
     900    {
     901        g_iSeqNoMaster++;
     902
     903        /*
     904         * Wait for the result.
     905         */
     906        uint64_t const msTimeout = RT_MS_1MIN / 2;
     907        uint64_t msStart         = RTTimeMilliTS();
     908        uint32_t msSleepX4       = 4;
     909        for (;;)
     910        {
     911            /* Try read the result file: */
     912            char *pszContent = NULL;
     913            rc = FsPerfCommsReadFile(g_iSeqNoMaster - 1, "-order.done", &pszContent);
     914            if (RT_SUCCESS(rc))
     915            {
     916                /* Split the result content into status code and error text: */
     917                char *pszErrorText = strchr(pszContent, '\n');
     918                if (pszErrorText)
     919                {
     920                    *pszErrorText = '\0';
     921                    pszErrorText++;
     922                }
     923                else
     924                {
     925                    char *pszEnd = strchr(pszContent, '\0');
     926                    Assert(pszEnd[-1] == FSPERF_EOF);
     927                    pszEnd[-1] = '\0';
     928                }
     929
     930                /* Parse the status code: */
     931                int32_t rcRemote = VERR_GENERAL_FAILURE;
     932                rc = RTStrToInt32Full(pszContent, 0,  &rcRemote);
     933                if (rc != VINF_SUCCESS)
     934                {
     935                    RTTestIFailed("FsPerfCommsSend: Failed to convert status code '%s'", pszContent);
     936                    rcRemote = VERR_GENERAL_FAILURE;
     937                }
     938
     939                /* Display or return the text? */
     940
     941                RTMemFree(pszContent);
     942                return rcRemote;
     943
     944            }
     945
     946            if (rc == VERR_TRY_AGAIN)
     947                msSleepX4 = 4;
     948
     949            /* Check for timeout. */
     950            if (RTTimeMilliTS() - msStart > msTimeout)
     951            {
     952                rc = RTFileDelete(InCommsSubDir(szSendNm, cchSendNm));
     953                if (RT_SUCCESS(rc))
     954                {
     955                    g_iSeqNoMaster--;
     956                    rc = VERR_TIMEOUT;
     957                }
     958                else if (RTFileExists(InCommsDir(szAckNm, cchAckNm)))
     959                    rc = VERR_PIPE_BUSY;
     960                else
     961                    rc = VERR_PIPE_IO_ERROR;
     962                break;
     963            }
     964
     965            /* Sleep a little while. */
     966            msSleepX4++;
     967            RTThreadSleep(msSleepX4 / 4);
     968        }
     969    }
     970    return rc;
     971}
     972
     973
     974/**
     975 * Shuts down the comms slave if it exists.
     976 */
     977static void FsPerfCommsShutdownSlave(void)
     978{
     979    static bool s_fAlreadyShutdown = false;
     980    if (g_szCommsDir[0] != '\0' && !s_fAlreadyShutdown)
     981    {
     982        s_fAlreadyShutdown = true;
     983        FsPerfCommsSend("exit" FSPERF_EOF_STR);
     984
     985        g_szCommsDir[g_cchCommsDir] = '\0';
     986        int rc = RTDirRemoveRecursive(g_szCommsDir, RTDIRRMREC_F_CONTENT_AND_DIR | (g_fRelativeDir ? RTDIRRMREC_F_NO_ABS_PATH : 0));
     987        if (RT_FAILURE(rc))
     988            RTTestFailed(g_hTest, "RTDirRemoveRecursive(%s,) -> %Rrc\n", g_szCommsDir, rc);
     989    }
     990}
     991
     992
     993
     994/*********************************************************************************************************************************
     995*   Comms Slave                                                                                                                  *
     996*********************************************************************************************************************************/
    855997
    856998typedef struct FSPERFCOMMSSLAVESTATE
     
    12121354
    12131355        offFile   += cbThisWrite;
    1214         cbToWrite += cbThisWrite;
     1356        cbToWrite -= cbThisWrite;
    12151357    }
    12161358
     
    14771619     */
    14781620    pState->iLineNo = 0;
    1479     while (*pszContent != 0x1a && *pszContent != '\0')
     1621    while (*pszContent != FSPERF_EOF && *pszContent != '\0')
    14801622    {
    14811623        pState->iLineNo++;
     
    14881630        else
    14891631        {
    1490             pszEol = strchr(pszLine, 0x1a);
     1632            pszEol = strchr(pszLine, FSPERF_EOF);
    14911633            AssertStmt(pszEol, pszEol = strchr(pszLine, '\0'));
    14921634            pszContent = pszEol;
     
    15321674     */
    15331675    char szTmp[_4K];
    1534     rc = FsPerfCommsWriteFile(RT_STR_TUPLE("slave.pid"), szTmp, RTStrPrintf(szTmp, sizeof(szTmp), "%u\x1a", RTProcSelf()));
     1676    rc = FsPerfCommsWriteFile(RT_STR_TUPLE("slave.pid"), szTmp, RTStrPrintf(szTmp, sizeof(szTmp),
     1677                                                                            "%u" FSPERF_EOF_STR, RTProcSelf()));
    15351678    if (RT_FAILURE(rc))
    15361679        return RTEXITCODE_FAILURE;
     
    15621705            char   szResult[64];
    15631706            size_t cchResult = RTStrPrintf(szResult, sizeof(szResult), "%u-order.done", State.iSeqNo);
    1564             size_t cchTmp    = RTStrPrintf(szTmp, sizeof(szTmp), "%d\n%s\x1a",
     1707            size_t cchTmp    = RTStrPrintf(szTmp, sizeof(szTmp), "%d\n%s" FSPERF_EOF_STR,
    15651708                                           rc, RTErrInfoIsSet(&State.ErrInfo.Core) ? State.ErrInfo.Core.pszMsg : "");
    1566             FsPerfCommsWriteFile(szResult, cchResult, szTmp, cchTmp);
     1709            FsPerfCommsWriteFileAndRename(szResult, cchResult, szTmp, cchTmp);
    15671710            State.iSeqNo++;
    15681711
     
    53195462
    53205463
     5464static void fsPerfRemote(void)
     5465{
     5466    RTTestISub("remote");
     5467    uint8_t abBuf[16384];
     5468
     5469
     5470    /*
     5471     * Create a file on the remote end and check that we can immediately see it.
     5472     */
     5473    RTTESTI_CHECK_RC_RETV(FsPerfCommsSend("reset\n"
     5474                                          "open         0 'file30' 'w' 'ca'\n"
     5475                                          "writepattern 0 0 0 4096\n" FSPERF_EOF_STR), VINF_SUCCESS);
     5476
     5477    RTFILEACTION enmActuallyTaken = RTFILEACTION_END;
     5478    RTFILE       hFile0 = NIL_RTFILE;
     5479    RTTESTI_CHECK_RC(RTFileOpenEx(InDir(RT_STR_TUPLE("file30")), RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_NONE,
     5480                                  &hFile0, &enmActuallyTaken), VINF_SUCCESS);
     5481    RTTESTI_CHECK(enmActuallyTaken == RTFILEACTION_OPENED);
     5482    RTTESTI_CHECK_RC(RTFileRead(hFile0, abBuf, 4096, NULL), VINF_SUCCESS);
     5483    AssertCompile(RT_ELEMENTS(g_abPattern0) == 1);
     5484    RTTESTI_CHECK(ASMMemIsAllU8(abBuf, 4096, g_abPattern0[0]));
     5485
     5486    RTTESTI_CHECK_RC(RTFileClose(hFile0), VINF_SUCCESS);
     5487
     5488}
     5489
     5490
     5491
    53215492/**
    53225493 * Display the usage to @a pStrm.
     
    55015672                g_fMMap      = true;
    55025673                g_fCopy      = true;
     5674                g_fRemote    = true;
    55035675                break;
    55045676
     
    55335705                g_fMMap      = false;
    55345706                g_fCopy      = false;
     5707                g_fRemote    = false;
    55355708                break;
    55365709
     
    55675740            CASE_OPT(IgnoreNoCache);
    55685741            CASE_OPT(Copy);
     5742            CASE_OPT(Remote);
    55695743
    55705744            CASE_OPT(ShowDuration);
     
    57545928                if (g_fCopy)
    57555929                    fsPerfCopy();
     5930                if (g_fRemote && g_szCommsDir[0] != '\0')
     5931                    fsPerfRemote();
    57565932            }
    57575933
    5758             /* Cleanup: */
     5934            /*
     5935             * Cleanup:
     5936             */
     5937            FsPerfCommsShutdownSlave();
     5938
    57595939            g_szDir[g_cchDir] = '\0';
    57605940            rc = RTDirRemoveRecursive(g_szDir, RTDIRRMREC_F_CONTENT_AND_DIR | (g_fRelativeDir ? RTDIRRMREC_F_NO_ABS_PATH : 0));
     
    57685948        RTTestFailed(g_hTest, "Test directory already exists: %s\n", g_szDir);
    57695949
     5950    FsPerfCommsShutdownSlave();
     5951
    57705952    return RTTestSummaryAndDestroy(g_hTest);
    57715953}
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