VirtualBox

Ignore:
Timestamp:
May 1, 2019 1:05:17 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

    r78359 r78360  
    652652
    653653
     654#if 0 // currently unused
    654655/**
    655656 * Construct a path relative to the comms sub-directory.
     
    666667    return &g_szCommsSubDir[0];
    667668}
     669#endif
    668670
    669671
     
    738740/**
    739741 * Reads the given file from the comms subdir, ensuring that it is terminated by
    740  * an EOF (0x1d) character.
     742 * an EOF (0x1a) character.
    741743 *
    742744 * @returns IPRT status code.
     
    759761    {
    760762        size_t cbUsed  = 0;
    761         size_t cbAlloc = 16; /// @todo _1K
     763        size_t cbAlloc = 1024;
    762764        char  *pszBuf  = (char *)RTMemAllocZ(cbAlloc);
    763765        for (;;)
     
    791793            size_t cbActual = 0;
    792794            rc = RTFileRead(hFile, &pszBuf[cbUsed], cbMaxRead, &cbActual);
    793             if (RT_FAILURE(rc))
     795            if (RT_SUCCESS(rc))
     796                cbUsed += cbActual;
     797            else
    794798            {
    795799                RTMsgError("Failed to read '%s': %Rrc", g_szCommsSubDir, rc);
     
    857861    RTFILE          ahFiles[8];
    858862    char           *apszFilenames[8];
     863
     864    /** The current command. */
     865    const char     *pszCommand;
    859866    /** The current line number. */
    860867    uint32_t        iLineNo;
     
    900907
    901908
    902 static int FsPerfSlaveSyntax(FSPERFCOMMSSLAVESTATE *pState, const char *pszError, ...)
     909/** Helper reporting a error. */
     910static int FsPerfSlaveError(FSPERFCOMMSSLAVESTATE *pState, int rc, const char *pszError, ...)
    903911{
    904912    va_list va;
    905913    va_start(va, pszError);
    906     RTErrInfoSetF(&pState->ErrInfo.Core, VERR_PARSE_ERROR, "line %u: syntax error: %N", pState->iLineNo, pszError, &va);
     914    RTErrInfoSetF(&pState->ErrInfo.Core, VERR_PARSE_ERROR, "line %u: %s: error: %N",
     915                  pState->iLineNo, pState->pszCommand, pszError, &va);
     916    va_end(va);
     917    return rc;
     918}
     919
     920
     921/** Helper reporting a syntax error. */
     922static int FsPerfSlaveSyntax(FSPERFCOMMSSLAVESTATE *pState, const char *pszError, ...)
     923{
     924    va_list va;
     925    va_start(va, pszError);
     926    RTErrInfoSetF(&pState->ErrInfo.Core, VERR_PARSE_ERROR, "line %u: %s: syntax error: %N",
     927                  pState->iLineNo, pState->pszCommand, pszError, &va);
    907928    va_end(va);
    908929    return VERR_PARSE_ERROR;
     
    910931
    911932
     933/** Helper for parsing an unsigned 64-bit integer argument. */
     934static int FsPerfSlaveParseU64(FSPERFCOMMSSLAVESTATE *pState, const char *pszArg, const char *pszName,
     935                               unsigned uBase, uint64_t uMin, uint64_t uLast, uint64_t *puValue)
     936{
     937    *puValue = uMin;
     938    uint64_t uValue;
     939    int rc = RTStrToUInt64Full(pszArg, uBase, &uValue);
     940    if (RT_FAILURE(rc))
     941        return FsPerfSlaveSyntax(pState, "invalid %s: %s (RTStrToUInt64Full -> %Rrc)", pszName, pszArg, rc);
     942    if (uValue < uMin || uValue > uLast)
     943        return FsPerfSlaveSyntax(pState, "%s is out of range: %u, valid range %u..%u", pszName, uValue, uMin, uLast);
     944    *puValue = uValue;
     945    return VINF_SUCCESS;
     946}
     947
     948
     949/** Helper for parsing an unsigned 32-bit integer argument. */
     950static int FsPerfSlaveParseU32(FSPERFCOMMSSLAVESTATE *pState, const char *pszArg, const char *pszName,
     951                               unsigned uBase, uint32_t uMin, uint32_t uLast, uint32_t *puValue)
     952{
     953    *puValue = uMin;
     954    uint32_t uValue;
     955    int rc = RTStrToUInt32Full(pszArg, uBase, &uValue);
     956    if (RT_FAILURE(rc))
     957        return FsPerfSlaveSyntax(pState, "invalid %s: %s (RTStrToUInt32Full -> %Rrc)", pszName, pszArg, rc);
     958    if (uValue < uMin || uValue > uLast)
     959        return FsPerfSlaveSyntax(pState, "%s is out of range: %u, valid range %u..%u", pszName, uValue, uMin, uLast);
     960    *puValue = uValue;
     961    return VINF_SUCCESS;
     962}
     963
     964
     965/** Helper for parsing a file handle index argument.   */
     966static int FsPerfSlaveParseFileIdx(FSPERFCOMMSSLAVESTATE *pState, const char *pszArg, uint32_t *pidxFile)
     967{
     968    return FsPerfSlaveParseU32(pState, pszArg, "file index", 0, 0, RT_ELEMENTS(pState->ahFiles) - 1, pidxFile);
     969}
     970
     971
     972/**
     973 * 'open {idxFile} {filename} {access} {disposition} [sharing] [mode]'
     974 */
    912975static int FsPerfSlaveHandleOpen(FSPERFCOMMSSLAVESTATE *pState, char **papszArgs, int cArgs)
    913976{
    914     RT_NOREF(pState, papszArgs, cArgs);
     977    /*
     978     * Parse parameters.
     979     */
     980    if (cArgs > 1 + 6 || cArgs < 1 + 4)
     981        return FsPerfSlaveSyntax(pState, "takes four to six arguments, not %u", cArgs);
     982
     983    uint32_t idxFile;
     984    int rc = FsPerfSlaveParseFileIdx(pState, papszArgs[1], &idxFile);
     985    if (RT_FAILURE(rc))
     986        return rc;
     987
     988    const char *pszFilename = papszArgs[2];
     989
     990    uint64_t fOpen = 0;
     991    rc = RTFileModeToFlagsEx(papszArgs[3], papszArgs[4], papszArgs[5], &fOpen);
     992    if (RT_FAILURE(rc))
     993        return FsPerfSlaveSyntax(pState, "failed to parse access (%s), disposition (%s) and sharing (%s): %Rrc",
     994                                 papszArgs[3], papszArgs[4], papszArgs[5] ? papszArgs[5] : "", rc);
     995
     996    uint32_t uMode = 0660;
     997    if (cArgs >= 1 + 6)
     998    {
     999        rc = FsPerfSlaveParseU32(pState, papszArgs[6], "mode", 8, 0, 0777, &uMode);
     1000        if (RT_FAILURE(rc))
     1001            return rc;
     1002        fOpen |= uMode << RTFILE_O_CREATE_MODE_SHIFT;
     1003    }
     1004
     1005    /*
     1006     * Is there already a file assigned to the file handle index?
     1007     */
     1008    if (pState->ahFiles[idxFile] != NIL_RTFILE)
     1009        return FsPerfSlaveError(pState, VERR_RESOURCE_BUSY, "handle #%u is already in use for '%s'",
     1010                                idxFile, pState->apszFilenames[idxFile]);
     1011
     1012    /*
     1013     * Check the filename length.
     1014     */
     1015    size_t const cchFilename = strlen(pszFilename);
     1016    if (g_cchDir + cchFilename >= sizeof(g_szDir))
     1017        return FsPerfSlaveError(pState, VERR_FILENAME_TOO_LONG, "'%.*s%s'", g_cchDir, g_szDir, pszFilename);
     1018
     1019    /*
     1020     * Duplicate the name and execute the command.
     1021     */
     1022    char *pszDup = RTStrDup(pszFilename);
     1023    if (!pszDup)
     1024        return FsPerfSlaveError(pState, VERR_NO_STR_MEMORY, "out of memory");
     1025
     1026    RTFILE hFile = NIL_RTFILE;
     1027    rc = RTFileOpen(&hFile, InDir(pszFilename, cchFilename), fOpen);
     1028    if (RT_SUCCESS(rc))
     1029    {
     1030        pState->ahFiles[idxFile]       = hFile;
     1031        pState->apszFilenames[idxFile] = pszDup;
     1032    }
     1033    else
     1034    {
     1035        RTStrFree(pszDup);
     1036        rc = FsPerfSlaveError(pState, rc, "%s: %Rrc", pszFilename, rc);
     1037    }
     1038    return rc;
     1039}
     1040
     1041
     1042/**
     1043 * 'close {idxFile}'
     1044 */
     1045static int FsPerfSlaveHandleClose(FSPERFCOMMSSLAVESTATE *pState, char **papszArgs, int cArgs)
     1046{
     1047    /*
     1048     * Parse parameters.
     1049     */
     1050    if (cArgs > 1 + 1)
     1051        return FsPerfSlaveSyntax(pState, "takes exactly one argument, not %u", cArgs);
     1052
     1053    uint32_t idxFile;
     1054    int rc = FsPerfSlaveParseFileIdx(pState, papszArgs[1], &idxFile);
     1055    if (RT_SUCCESS(rc))
     1056    {
     1057        /*
     1058         * Do it.
     1059         */
     1060        rc = RTFileClose(pState->ahFiles[idxFile]);
     1061        if (RT_SUCCESS(rc))
     1062        {
     1063            pState->ahFiles[idxFile] = NIL_RTFILE;
     1064            RTStrFree(pState->apszFilenames[idxFile]);
     1065            pState->apszFilenames[idxFile] = NULL;
     1066        }
     1067    }
     1068    return rc;
     1069}
     1070
     1071/** @name Patterns for 'writepattern'
     1072 * @{ */
     1073static uint8_t const g_abPattern0[]  = { 0xf0 };
     1074static uint8_t const g_abPattern1[]  = { 0xf1 };
     1075static uint8_t const g_abPattern2[]  = { 0xf2 };
     1076static uint8_t const g_abPattern3[]  = { 0xf3 };
     1077static uint8_t const g_abPattern4[]  = { 0xf4 };
     1078static uint8_t const g_abPattern5[]  = { 0xf5 };
     1079static uint8_t const g_abPattern6[]  = { 0xf6 };
     1080static uint8_t const g_abPattern7[]  = { 0xf7 };
     1081static uint8_t const g_abPattern8[]  = { 0xf8 };
     1082static uint8_t const g_abPattern9[]  = { 0xf9 };
     1083static uint8_t const g_abPattern10[] = { 0x1f, 0x4e, 0x99, 0xec, 0x71, 0x71, 0x48, 0x0f, 0xa7, 0x5c, 0xb4, 0x5a, 0x1f, 0xc7, 0xd0, 0x93 };
     1084static struct
     1085{
     1086    uint8_t const  *pb;
     1087    uint32_t        cb;
     1088} const g_aPatterns[] =
     1089{
     1090    { g_abPattern0,  sizeof(g_abPattern0) },
     1091    { g_abPattern1,  sizeof(g_abPattern1) },
     1092    { g_abPattern2,  sizeof(g_abPattern2) },
     1093    { g_abPattern3,  sizeof(g_abPattern3) },
     1094    { g_abPattern4,  sizeof(g_abPattern4) },
     1095    { g_abPattern5,  sizeof(g_abPattern5) },
     1096    { g_abPattern6,  sizeof(g_abPattern6) },
     1097    { g_abPattern7,  sizeof(g_abPattern7) },
     1098    { g_abPattern8,  sizeof(g_abPattern8) },
     1099    { g_abPattern9,  sizeof(g_abPattern9) },
     1100    { g_abPattern10, sizeof(g_abPattern10) },
     1101};
     1102/** @} */
     1103
     1104/**
     1105 * 'writepattern {idxFile} {offFile} {idxPattern} {cbToWrite}'
     1106 */
     1107static int FsPerfSlaveHandleWritePattern(FSPERFCOMMSSLAVESTATE *pState, char **papszArgs, int cArgs)
     1108{
     1109    /*
     1110     * Parse parameters.
     1111     */
     1112    if (cArgs > 1 + 4)
     1113        return FsPerfSlaveSyntax(pState, "takes exactly four arguments, not %u", cArgs);
     1114
     1115    uint32_t idxFile;
     1116    int rc = FsPerfSlaveParseFileIdx(pState, papszArgs[1], &idxFile);
     1117    if (RT_FAILURE(rc))
     1118        return rc;
     1119
     1120    uint64_t offFile;
     1121    rc = FsPerfSlaveParseU64(pState, papszArgs[2], "file offset", 0, 0, UINT64_MAX / 4, &offFile);
     1122    if (RT_FAILURE(rc))
     1123        return rc;
     1124
     1125    uint32_t idxPattern;
     1126    rc = FsPerfSlaveParseU32(pState, papszArgs[3], "pattern index", 0, 0, RT_ELEMENTS(g_aPatterns) - 1, &idxPattern);
     1127    if (RT_FAILURE(rc))
     1128        return rc;
     1129
     1130    uint64_t cbToWrite;
     1131    rc = FsPerfSlaveParseU64(pState, papszArgs[4], "number of bytes to write", 0, 0, _1G, &cbToWrite);
     1132    if (RT_FAILURE(rc))
     1133        return rc;
     1134
     1135    if (pState->ahFiles[idxFile] == NIL_RTFILE)
     1136        return FsPerfSlaveError(pState, VERR_INVALID_HANDLE, "no open file at index #%u", idxFile);
     1137
     1138    /*
     1139     * Allocate a suitable buffer.
     1140     */
     1141    size_t   cbBuf = cbToWrite >= _2M ? _2M : RT_ALIGN_Z((size_t)cbToWrite, 512);
     1142    uint8_t *pbBuf = (uint8_t *)RTMemTmpAlloc(cbBuf);
     1143    if (!pbBuf)
     1144    {
     1145        cbBuf = _4K;
     1146        pbBuf = (uint8_t *)RTMemTmpAlloc(cbBuf);
     1147        if (!pbBuf)
     1148            return FsPerfSlaveError(pState, VERR_NO_TMP_MEMORY, "failed to allocate 4KB for buffers");
     1149    }
     1150
     1151    /*
     1152     * Fill 1 byte patterns before we start looping.
     1153     */
     1154    if (g_aPatterns[idxPattern].cb == 1)
     1155        memset(pbBuf, g_aPatterns[idxPattern].pb[0], cbBuf);
     1156
     1157    /*
     1158     * The write loop.
     1159     */
     1160    uint32_t offPattern = 0;
     1161    while (cbToWrite > 0)
     1162    {
     1163        /*
     1164         * Fill the buffer if multi-byte pattern (single byte patterns are handled before the loop):
     1165         */
     1166        if (g_aPatterns[idxPattern].cb > 1)
     1167        {
     1168            uint32_t const        cbSrc = g_aPatterns[idxPattern].cb;
     1169            uint8_t const * const pbSrc = g_aPatterns[idxPattern].pb;
     1170            size_t                cbDst = cbBuf;
     1171            uint8_t              *pbDst = pbBuf;
     1172
     1173            /* first iteration, potential partial pattern. */
     1174            if (offPattern >= cbSrc)
     1175                offPattern = 0;
     1176            size_t cbThis1 = RT_MIN(g_aPatterns[idxPattern].cb - offPattern, cbToWrite);
     1177            memcpy(pbDst, &pbSrc[offPattern], cbThis1);
     1178            cbDst -= cbThis1;
     1179            if (cbDst > 0)
     1180            {
     1181                pbDst += cbThis1;
     1182                offPattern = 0;
     1183
     1184                /* full patterns */
     1185                while (cbDst >= cbSrc)
     1186                {
     1187                    memcpy(pbDst, pbSrc, cbSrc);
     1188                    pbDst += cbSrc;
     1189                    cbDst -= cbSrc;
     1190                }
     1191
     1192                /* partial final copy */
     1193                if (cbDst > 0)
     1194                {
     1195                    memcpy(pbDst, pbSrc, cbDst);
     1196                    offPattern = (uint32_t)cbDst;
     1197                }
     1198            }
     1199        }
     1200
     1201        /*
     1202         * Write.
     1203         */
     1204        size_t const cbThisWrite = (size_t)RT_MIN(cbToWrite, cbBuf);
     1205        rc = RTFileWriteAt(pState->ahFiles[idxFile], offFile, pbBuf, cbThisWrite, NULL);
     1206        if (RT_FAILURE(rc))
     1207        {
     1208            FsPerfSlaveError(pState, rc, "error writing %#zx bytes at %#RX64: %Rrc (file: %s)",
     1209                             cbThisWrite, offFile, rc, pState->apszFilenames[idxFile]);
     1210            break;
     1211        }
     1212
     1213        offFile   += cbThisWrite;
     1214        cbToWrite += cbThisWrite;
     1215    }
     1216
     1217    RTMemTmpFree(pbBuf);
     1218    return rc;
     1219}
     1220
     1221
     1222/**
     1223 * 'truncate {idxFile} {cbFile}'
     1224 */
     1225static int FsPerfSlaveHandleTruncate(FSPERFCOMMSSLAVESTATE *pState, char **papszArgs, int cArgs)
     1226{
     1227    /*
     1228     * Parse parameters.
     1229     */
     1230    if (cArgs != 1 + 2)
     1231        return FsPerfSlaveSyntax(pState, "takes exactly two arguments, not %u", cArgs);
     1232
     1233    uint32_t idxFile;
     1234    int rc = FsPerfSlaveParseFileIdx(pState, papszArgs[1], &idxFile);
     1235    if (RT_FAILURE(rc))
     1236        return rc;
     1237
     1238    uint64_t cbFile;
     1239    rc = FsPerfSlaveParseU64(pState, papszArgs[2], "new file size", 0, 0, UINT64_MAX / 4, &cbFile);
     1240    if (RT_FAILURE(rc))
     1241        return rc;
     1242
     1243    if (pState->ahFiles[idxFile] == NIL_RTFILE)
     1244        return FsPerfSlaveError(pState, VERR_INVALID_HANDLE, "no open file at index #%u", idxFile);
     1245
     1246    /*
     1247     * Execute.
     1248     */
     1249    rc = RTFileSetSize(pState->ahFiles[idxFile], cbFile);
     1250    if (RT_FAILURE(rc))
     1251        return FsPerfSlaveError(pState, rc, "failed to set file size to %#RX64: %Rrc (file: %s)",
     1252                                cbFile, rc, pState->apszFilenames[idxFile]);
    9151253    return VINF_SUCCESS;
    9161254}
    9171255
    9181256
    919 static int FsPerfSlaveHandleClose(FSPERFCOMMSSLAVESTATE *pState, char **papszArgs, int cArgs)
     1257/**
     1258 * 'futimes {idxFile} {modified|0} [access|0] [change|0] [birth|0]'
     1259 */
     1260static int FsPerfSlaveHandleFUTimes(FSPERFCOMMSSLAVESTATE *pState, char **papszArgs, int cArgs)
    9201261{
    9211262    /*
    9221263     * Parse parameters.
    9231264     */
    924     if (cArgs != 1 + 1)
    925         return FsPerfSlaveSyntax(pState, "The 'close' command takes 1 argument, not %u", cArgs);
     1265    if (cArgs < 1 + 2 || cArgs > 1 + 5)
     1266        return FsPerfSlaveSyntax(pState, "takes between two and five arguments, not %u", cArgs);
     1267
    9261268    uint32_t idxFile;
    927     int rc = RTStrToUInt32Full(papszArgs[1], 0, &idxFile);
     1269    int rc = FsPerfSlaveParseFileIdx(pState, papszArgs[1], &idxFile);
    9281270    if (RT_FAILURE(rc))
    929         return FsPerfSlaveSyntax(pState, "Invalid 'close' argument #1 (%Rrc): %s", rc, papszArgs[1]);
    930     if (idxFile >= RT_ELEMENTS(pState->ahFiles))
    931         return FsPerfSlaveSyntax(pState, "The 'close' argument idxFile is out of range: %u", idxFile);
    932 
    933     /*
    934      * Do it.
    935      */
    936     rc = RTFileClose(pState->ahFiles[idxFile]);
    937     if (RT_SUCCESS(rc))
    938         pState->ahFiles[idxFile] = NIL_RTFILE;
    939 
    940     return rc;
     1271        return rc;
     1272
     1273    uint64_t nsModifiedTime;
     1274    rc = FsPerfSlaveParseU64(pState, papszArgs[2], "modified time", 0, 0, UINT64_MAX, &nsModifiedTime);
     1275    if (RT_FAILURE(rc))
     1276        return rc;
     1277
     1278    uint64_t nsAccessTime = 0;
     1279    if (cArgs >= 1 + 3)
     1280    {
     1281        rc = FsPerfSlaveParseU64(pState, papszArgs[3], "access time", 0, 0, UINT64_MAX, &nsAccessTime);
     1282        if (RT_FAILURE(rc))
     1283            return rc;
     1284    }
     1285
     1286    uint64_t nsChangeTime = 0;
     1287    if (cArgs >= 1 + 4)
     1288    {
     1289        rc = FsPerfSlaveParseU64(pState, papszArgs[4], "change time", 0, 0, UINT64_MAX, &nsChangeTime);
     1290        if (RT_FAILURE(rc))
     1291            return rc;
     1292    }
     1293
     1294    uint64_t nsBirthTime = 0;
     1295    if (cArgs >= 1 + 5)
     1296    {
     1297        rc = FsPerfSlaveParseU64(pState, papszArgs[4], "birth time", 0, 0, UINT64_MAX, &nsBirthTime);
     1298        if (RT_FAILURE(rc))
     1299            return rc;
     1300    }
     1301
     1302    if (pState->ahFiles[idxFile] == NIL_RTFILE)
     1303        return FsPerfSlaveError(pState, VERR_INVALID_HANDLE, "no open file at index #%u", idxFile);
     1304
     1305    /*
     1306     * Execute.
     1307     */
     1308    RTTIMESPEC ModifiedTime;
     1309    RTTIMESPEC AccessTime;
     1310    RTTIMESPEC ChangeTime;
     1311    RTTIMESPEC BirthTime;
     1312    rc = RTFileSetTimes(pState->ahFiles[idxFile],
     1313                        nsAccessTime   ? RTTimeSpecSetNano(&AccessTime, nsAccessTime) : NULL,
     1314                        nsModifiedTime ? RTTimeSpecSetNano(&ModifiedTime, nsModifiedTime) : NULL,
     1315                        nsChangeTime   ? RTTimeSpecSetNano(&ChangeTime, nsChangeTime) : NULL,
     1316                        nsBirthTime    ? RTTimeSpecSetNano(&BirthTime, nsBirthTime) : NULL);
     1317    if (RT_FAILURE(rc))
     1318        return FsPerfSlaveError(pState, rc, "failed to set file times to %RI64, %RI64, %RI64, %RI64: %Rrc (file: %s)",
     1319                                nsModifiedTime, nsAccessTime, nsChangeTime, nsBirthTime, rc, pState->apszFilenames[idxFile]);
     1320    return VINF_SUCCESS;
     1321}
     1322
     1323
     1324/**
     1325 * 'fchmod {idxFile} {cbFile}'
     1326 */
     1327static int FsPerfSlaveHandleFChMod(FSPERFCOMMSSLAVESTATE *pState, char **papszArgs, int cArgs)
     1328{
     1329    /*
     1330     * Parse parameters.
     1331     */
     1332    if (cArgs != 1 + 2)
     1333        return FsPerfSlaveSyntax(pState, "takes exactly two arguments, not %u", cArgs);
     1334
     1335    uint32_t idxFile;
     1336    int rc = FsPerfSlaveParseFileIdx(pState, papszArgs[1], &idxFile);
     1337    if (RT_FAILURE(rc))
     1338        return rc;
     1339
     1340    uint32_t fAttribs;
     1341    rc = FsPerfSlaveParseU32(pState, papszArgs[2], "new file attributes", 0, 0, UINT32_MAX, &fAttribs);
     1342    if (RT_FAILURE(rc))
     1343        return rc;
     1344
     1345    if (pState->ahFiles[idxFile] == NIL_RTFILE)
     1346        return FsPerfSlaveError(pState, VERR_INVALID_HANDLE, "no open file at index #%u", idxFile);
     1347
     1348    /*
     1349     * Execute.
     1350     */
     1351    rc = RTFileSetMode(pState->ahFiles[idxFile], fAttribs);
     1352    if (RT_FAILURE(rc))
     1353        return FsPerfSlaveError(pState, rc, "failed to set file mode to %#RX32: %Rrc (file: %s)",
     1354                                fAttribs, rc, pState->apszFilenames[idxFile]);
     1355    return VINF_SUCCESS;
     1356}
     1357
     1358
     1359/**
     1360 * 'reset'
     1361 */
     1362static int FsPerfSlaveHandleReset(FSPERFCOMMSSLAVESTATE *pState, char **papszArgs, int cArgs)
     1363{
     1364    /*
     1365     * Parse parameters.
     1366     */
     1367    if (cArgs > 1)
     1368        return FsPerfSlaveSyntax(pState, "takes zero arguments, not %u", cArgs);
     1369    RT_NOREF(papszArgs);
     1370
     1371    /*
     1372     * Execute the command.
     1373     */
     1374    FsPerfSlaveStateCleanup(pState);
     1375    return VINF_SUCCESS;
     1376}
     1377
     1378
     1379/**
     1380 * 'exit [exitcode]'
     1381 */
     1382static int FsPerfSlaveHandleExit(FSPERFCOMMSSLAVESTATE *pState, char **papszArgs, int cArgs)
     1383{
     1384    /*
     1385     * Parse parameters.
     1386     */
     1387    if (cArgs > 1 + 1)
     1388        return FsPerfSlaveSyntax(pState, "takes zero or one argument, not %u", cArgs);
     1389
     1390    if (cArgs >= 1 + 1)
     1391    {
     1392        uint32_t uExitCode;
     1393        int rc = FsPerfSlaveParseU32(pState, papszArgs[1], "exit code", 0, 0, 127, &uExitCode);
     1394        if (RT_FAILURE(rc))
     1395            return rc;
     1396
     1397        /*
     1398         * Execute the command.
     1399         */
     1400        pState->rcExit = (RTEXITCODE)uExitCode;
     1401    }
     1402    pState->fTerminate = true;
     1403    return VINF_SUCCESS;
    9411404}
    9421405
     
    9711434    } s_aHandlers[] =
    9721435    {
    973         { RT_STR_TUPLE("open"),     FsPerfSlaveHandleOpen },
    974         { RT_STR_TUPLE("close"),    FsPerfSlaveHandleClose },
     1436        { RT_STR_TUPLE("open"),         FsPerfSlaveHandleOpen },
     1437        { RT_STR_TUPLE("close"),        FsPerfSlaveHandleClose },
     1438        { RT_STR_TUPLE("writepattern"), FsPerfSlaveHandleWritePattern },
     1439        { RT_STR_TUPLE("truncate"),     FsPerfSlaveHandleTruncate },
     1440        { RT_STR_TUPLE("futimes"),      FsPerfSlaveHandleFUTimes},
     1441        { RT_STR_TUPLE("fchmod"),       FsPerfSlaveHandleFChMod },
     1442        { RT_STR_TUPLE("reset"),        FsPerfSlaveHandleReset },
     1443        { RT_STR_TUPLE("exit"),         FsPerfSlaveHandleExit },
    9751444    };
    9761445    const char * const pszCmd = papszArgs[0];
     
    9801449            && memcmp(pszCmd, s_aHandlers[i].pszCmd, cchCmd) == 0)
    9811450        {
     1451            pState->pszCommand = s_aHandlers[i].pszCmd;
    9821452            rc = s_aHandlers[i].pfnHandler(pState, papszArgs, cArgs);
    9831453            RTGetOptArgvFree(papszArgs);
     
    10071477     */
    10081478    pState->iLineNo = 0;
    1009     while (*pszContent != 0x1d && *pszContent != '\0')
     1479    while (*pszContent != 0x1a && *pszContent != '\0')
    10101480    {
    10111481        pState->iLineNo++;
     
    10181488        else
    10191489        {
    1020             pszEol = strchr(pszLine, 0x1d);
     1490            pszEol = strchr(pszLine, 0x1a);
    10211491            AssertStmt(pszEol, pszEol = strchr(pszLine, '\0'));
    10221492            pszContent = pszEol;
     
    10621532     */
    10631533    char szTmp[_4K];
    1064     rc = FsPerfCommsWriteFile(RT_STR_TUPLE("slave.pid"), szTmp, RTStrPrintf(szTmp, sizeof(szTmp), "%u\x1d", RTProcSelf()));
     1534    rc = FsPerfCommsWriteFile(RT_STR_TUPLE("slave.pid"), szTmp, RTStrPrintf(szTmp, sizeof(szTmp), "%u\x1a", RTProcSelf()));
    10651535    if (RT_FAILURE(rc))
    10661536        return RTEXITCODE_FAILURE;
     
    10711541    FSPERFCOMMSSLAVESTATE State;
    10721542    FsPerfSlaveStateInit(&State);
     1543    uint32_t msSleep = 1;
    10731544    while (!State.fTerminate)
    10741545    {
     
    10911562            char   szResult[64];
    10921563            size_t cchResult = RTStrPrintf(szResult, sizeof(szResult), "%u-order.done", State.iSeqNo);
    1093             size_t cchTmp    = RTStrPrintf(szTmp, sizeof(szTmp), "%d\n%s\x1d",
     1564            size_t cchTmp    = RTStrPrintf(szTmp, sizeof(szTmp), "%d\n%s\x1a",
    10941565                                           rc, RTErrInfoIsSet(&State.ErrInfo.Core) ? State.ErrInfo.Core.pszMsg : "");
    10951566            FsPerfCommsWriteFile(szResult, cchResult, szTmp, cchTmp);
    10961567            State.iSeqNo++;
     1568
     1569            msSleep = 1;
    10971570        }
    10981571
     
    11001573         * Wait a little and check again.
    11011574         */
    1102         if (rc == VERR_TRY_AGAIN || rc == VERR_SHARING_VIOLATION)
    1103             RTThreadSleep(8);
    1104         else
    1105             RTThreadSleep(64);
     1575        RTThreadSleep(msSleep);
     1576        if (msSleep < 128)
     1577            msSleep++;
    11061578    }
    11071579
     
    11141586}
    11151587
     1588
     1589
     1590/*********************************************************************************************************************************
     1591*   Tests                                                                                                                        *
     1592*********************************************************************************************************************************/
    11161593
    11171594/**
     
    49595436                g_cchCommsDir = strlen(g_szCommsDir);
    49605437
    4961                 rc = RTPathAppend(g_szCommsSubDir, sizeof(g_szCommsSubDir) - 128, "comms" RTPATH_SLASH_STR);
     5438                rc = RTPathJoin(g_szCommsSubDir, sizeof(g_szCommsSubDir) - 128, g_szCommsDir, "comms" RTPATH_SLASH_STR);
    49625439                if (RT_FAILURE(rc))
    49635440                {
    4964                     RTTestFailed(g_hTest, "RTPathAppend(%s,,'comms/') failed: %Rrc\n", g_szCommsDir, rc);
     5441                    RTTestFailed(g_hTest, "RTPathJoin(%s,,'comms/') failed: %Rrc\n", g_szCommsDir, rc);
    49655442                    return RTTestSummaryAndDestroy(g_hTest);
    49665443                }
     
    51925669
    51935670    /*
    5194      * If communcation slave, go do that and be done.
    5195      */
    5196     if (fCommsSlave)
    5197         return FsPerfCommsSlave();
    5198 
    5199     /*
    52005671     * Populate g_szDir.
    52015672     */
     
    52115682    RTPathEnsureTrailingSeparator(g_szDir, sizeof(g_szDir));
    52125683    g_cchDir = strlen(g_szDir);
     5684
     5685    /*
     5686     * If communication slave, go do that and be done.
     5687     */
     5688    if (fCommsSlave)
     5689    {
     5690        if (pszDir == szDefaultDir)
     5691            return RTMsgErrorExit(RTEXITCODE_SYNTAX, "The slave must have a working directory specified (-d)!");
     5692        return FsPerfCommsSlave();
     5693    }
    52135694
    52145695    /*
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