- Timestamp:
- May 1, 2019 1:05:17 AM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/ValidationKit/utils/fs/FsPerf.cpp
r78359 r78360 652 652 653 653 654 #if 0 // currently unused 654 655 /** 655 656 * Construct a path relative to the comms sub-directory. … … 666 667 return &g_szCommsSubDir[0]; 667 668 } 669 #endif 668 670 669 671 … … 738 740 /** 739 741 * Reads the given file from the comms subdir, ensuring that it is terminated by 740 * an EOF (0x1 d) character.742 * an EOF (0x1a) character. 741 743 * 742 744 * @returns IPRT status code. … … 759 761 { 760 762 size_t cbUsed = 0; 761 size_t cbAlloc = 1 6; /// @todo _1K763 size_t cbAlloc = 1024; 762 764 char *pszBuf = (char *)RTMemAllocZ(cbAlloc); 763 765 for (;;) … … 791 793 size_t cbActual = 0; 792 794 rc = RTFileRead(hFile, &pszBuf[cbUsed], cbMaxRead, &cbActual); 793 if (RT_FAILURE(rc)) 795 if (RT_SUCCESS(rc)) 796 cbUsed += cbActual; 797 else 794 798 { 795 799 RTMsgError("Failed to read '%s': %Rrc", g_szCommsSubDir, rc); … … 857 861 RTFILE ahFiles[8]; 858 862 char *apszFilenames[8]; 863 864 /** The current command. */ 865 const char *pszCommand; 859 866 /** The current line number. */ 860 867 uint32_t iLineNo; … … 900 907 901 908 902 static int FsPerfSlaveSyntax(FSPERFCOMMSSLAVESTATE *pState, const char *pszError, ...) 909 /** Helper reporting a error. */ 910 static int FsPerfSlaveError(FSPERFCOMMSSLAVESTATE *pState, int rc, const char *pszError, ...) 903 911 { 904 912 va_list va; 905 913 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. */ 922 static 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); 907 928 va_end(va); 908 929 return VERR_PARSE_ERROR; … … 910 931 911 932 933 /** Helper for parsing an unsigned 64-bit integer argument. */ 934 static 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. */ 950 static 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. */ 966 static 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 */ 912 975 static int FsPerfSlaveHandleOpen(FSPERFCOMMSSLAVESTATE *pState, char **papszArgs, int cArgs) 913 976 { 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 */ 1045 static 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 * @{ */ 1073 static uint8_t const g_abPattern0[] = { 0xf0 }; 1074 static uint8_t const g_abPattern1[] = { 0xf1 }; 1075 static uint8_t const g_abPattern2[] = { 0xf2 }; 1076 static uint8_t const g_abPattern3[] = { 0xf3 }; 1077 static uint8_t const g_abPattern4[] = { 0xf4 }; 1078 static uint8_t const g_abPattern5[] = { 0xf5 }; 1079 static uint8_t const g_abPattern6[] = { 0xf6 }; 1080 static uint8_t const g_abPattern7[] = { 0xf7 }; 1081 static uint8_t const g_abPattern8[] = { 0xf8 }; 1082 static uint8_t const g_abPattern9[] = { 0xf9 }; 1083 static uint8_t const g_abPattern10[] = { 0x1f, 0x4e, 0x99, 0xec, 0x71, 0x71, 0x48, 0x0f, 0xa7, 0x5c, 0xb4, 0x5a, 0x1f, 0xc7, 0xd0, 0x93 }; 1084 static 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 */ 1107 static 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 */ 1225 static 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]); 915 1253 return VINF_SUCCESS; 916 1254 } 917 1255 918 1256 919 static int FsPerfSlaveHandleClose(FSPERFCOMMSSLAVESTATE *pState, char **papszArgs, int cArgs) 1257 /** 1258 * 'futimes {idxFile} {modified|0} [access|0] [change|0] [birth|0]' 1259 */ 1260 static int FsPerfSlaveHandleFUTimes(FSPERFCOMMSSLAVESTATE *pState, char **papszArgs, int cArgs) 920 1261 { 921 1262 /* 922 1263 * Parse parameters. 923 1264 */ 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 926 1268 uint32_t idxFile; 927 int rc = RTStrToUInt32Full(papszArgs[1], 0, &idxFile);1269 int rc = FsPerfSlaveParseFileIdx(pState, papszArgs[1], &idxFile); 928 1270 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 */ 1327 static 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 */ 1362 static 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 */ 1382 static 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; 941 1404 } 942 1405 … … 971 1434 } s_aHandlers[] = 972 1435 { 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 }, 975 1444 }; 976 1445 const char * const pszCmd = papszArgs[0]; … … 980 1449 && memcmp(pszCmd, s_aHandlers[i].pszCmd, cchCmd) == 0) 981 1450 { 1451 pState->pszCommand = s_aHandlers[i].pszCmd; 982 1452 rc = s_aHandlers[i].pfnHandler(pState, papszArgs, cArgs); 983 1453 RTGetOptArgvFree(papszArgs); … … 1007 1477 */ 1008 1478 pState->iLineNo = 0; 1009 while (*pszContent != 0x1 d&& *pszContent != '\0')1479 while (*pszContent != 0x1a && *pszContent != '\0') 1010 1480 { 1011 1481 pState->iLineNo++; … … 1018 1488 else 1019 1489 { 1020 pszEol = strchr(pszLine, 0x1 d);1490 pszEol = strchr(pszLine, 0x1a); 1021 1491 AssertStmt(pszEol, pszEol = strchr(pszLine, '\0')); 1022 1492 pszContent = pszEol; … … 1062 1532 */ 1063 1533 char szTmp[_4K]; 1064 rc = FsPerfCommsWriteFile(RT_STR_TUPLE("slave.pid"), szTmp, RTStrPrintf(szTmp, sizeof(szTmp), "%u\x1 d", RTProcSelf()));1534 rc = FsPerfCommsWriteFile(RT_STR_TUPLE("slave.pid"), szTmp, RTStrPrintf(szTmp, sizeof(szTmp), "%u\x1a", RTProcSelf())); 1065 1535 if (RT_FAILURE(rc)) 1066 1536 return RTEXITCODE_FAILURE; … … 1071 1541 FSPERFCOMMSSLAVESTATE State; 1072 1542 FsPerfSlaveStateInit(&State); 1543 uint32_t msSleep = 1; 1073 1544 while (!State.fTerminate) 1074 1545 { … … 1091 1562 char szResult[64]; 1092 1563 size_t cchResult = RTStrPrintf(szResult, sizeof(szResult), "%u-order.done", State.iSeqNo); 1093 size_t cchTmp = RTStrPrintf(szTmp, sizeof(szTmp), "%d\n%s\x1 d",1564 size_t cchTmp = RTStrPrintf(szTmp, sizeof(szTmp), "%d\n%s\x1a", 1094 1565 rc, RTErrInfoIsSet(&State.ErrInfo.Core) ? State.ErrInfo.Core.pszMsg : ""); 1095 1566 FsPerfCommsWriteFile(szResult, cchResult, szTmp, cchTmp); 1096 1567 State.iSeqNo++; 1568 1569 msSleep = 1; 1097 1570 } 1098 1571 … … 1100 1573 * Wait a little and check again. 1101 1574 */ 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++; 1106 1578 } 1107 1579 … … 1114 1586 } 1115 1587 1588 1589 1590 /********************************************************************************************************************************* 1591 * Tests * 1592 *********************************************************************************************************************************/ 1116 1593 1117 1594 /** … … 4959 5436 g_cchCommsDir = strlen(g_szCommsDir); 4960 5437 4961 rc = RTPath Append(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); 4962 5439 if (RT_FAILURE(rc)) 4963 5440 { 4964 RTTestFailed(g_hTest, "RTPath Append(%s,,'comms/') failed: %Rrc\n", g_szCommsDir, rc);5441 RTTestFailed(g_hTest, "RTPathJoin(%s,,'comms/') failed: %Rrc\n", g_szCommsDir, rc); 4965 5442 return RTTestSummaryAndDestroy(g_hTest); 4966 5443 } … … 5192 5669 5193 5670 /* 5194 * If communcation slave, go do that and be done.5195 */5196 if (fCommsSlave)5197 return FsPerfCommsSlave();5198 5199 /*5200 5671 * Populate g_szDir. 5201 5672 */ … … 5211 5682 RTPathEnsureTrailingSeparator(g_szDir, sizeof(g_szDir)); 5212 5683 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 } 5213 5694 5214 5695 /*
Note:
See TracChangeset
for help on using the changeset viewer.