📄 fsx.c
字号:
log4(OP_TRUNCATE, size, (unsigned)file_size, 0, &t); if (size > file_size) memset(good_buf + file_size, '\0', size - file_size); file_size = size; if (testcalls <= simulatedopcount) return; output_line(tf, OP_TRUNCATE, oldsize, size, &t); if (ftruncate(fd, (off_t)size) == -1) { prt("ftruncate1: %x\n", size); prterr("dotruncate: ftruncate"); report_failure(160); } if (!quiet && debug > 1) { gettimeofday(&t, NULL); prt(" %lu.%06lu trunc done\n", t.tv_sec, t.tv_usec); }}voidwritefileimage(){ ssize_t iret; int fd = get_fd(); if (lseek(fd, (off_t)0, SEEK_SET) == (off_t)-1) { prterr("writefileimage: lseek"); report_failure(171); } iret = write(fd, good_buf, file_size); if ((off_t)iret != file_size) { if (iret == -1) prterr("writefileimage: write"); else prt("short write: 0x%lx bytes instead of 0x%llx\n", (unsigned long)iret, (unsigned long long)file_size); report_failure(172); } if (lite ? 0 : ftruncate(fd, file_size) == -1) { prt("ftruncate2: %llx\n", (unsigned long long)file_size); prterr("writefileimage: ftruncate"); report_failure(173); }}voiddocloseopen(void){ struct timeval t; struct test_file *tf = get_tf(); if (testcalls <= simulatedopcount) return; gettimeofday(&t, NULL); log4(OP_CLOSEOPEN, file_size, (unsigned)file_size, 0, &t); if (debug) prt("%06lu %lu.%06lu close/open\n", testcalls, t.tv_sec, t.tv_usec); if (close(tf->fd)) { prterr("docloseopen: close"); report_failure(180); } if (!quiet && debug > 1) { gettimeofday(&t, NULL); prt(" %lu.%06lu close done\n", t.tv_sec, t.tv_usec); } tf->fd = open(tf->path, O_RDWR, 0); if (tf->fd < 0) { prterr("docloseopen: open"); report_failure(181); } if (!quiet && debug > 1) { gettimeofday(&t, NULL); prt(" %lu.%06lu open done\n", t.tv_sec, t.tv_usec); }}voidtest(void){ unsigned long offset; unsigned long size = maxoplen; unsigned long rv = random(); unsigned long op = rv % (3 + !lite + mapped_writes); /* turn off the map read if necessary */ if (op == 2 && !mapped_reads) op = 0; if (simulatedopcount > 0 && testcalls == simulatedopcount) writefileimage(); testcalls++; if (debugstart > 0 && testcalls >= debugstart) debug = 1; if (!quiet && testcalls < simulatedopcount && testcalls % 100000 == 0) prt("%lu...\n", testcalls); /* * READ: op = 0 * WRITE: op = 1 * MAPREAD: op = 2 * TRUNCATE: op = 3 * MAPWRITE: op = 3 or 4 */ if (lite ? 0 : op == 3 && (style & 1) == 0) /* vanilla truncate? */ dotruncate(random() % maxfilelen); else { if (randomoplen) size = random() % (maxoplen+1); if (lite ? 0 : op == 3) dotruncate(size); else { offset = random(); if (op == 1 || op == (lite ? 3 : 4)) { offset %= maxfilelen; if (offset + size > maxfilelen) size = maxfilelen - offset; if (op != 1) domapwrite(offset, size); else dowrite(offset, size); } else { if (file_size) offset %= file_size; else offset = 0; if (offset + size > file_size) size = file_size - offset; if (op != 0) domapread(offset, size); else doread(offset, size); } } } if (sizechecks && testcalls > simulatedopcount) check_size(); if (closeprob && (rv >> 3) < (1 << 28) / closeprob) docloseopen();}voidcleanup(sig) int sig;{ if (sig) prt("signal %d\n", sig); prt("testcalls = %lu\n", testcalls); exit(sig);}voidusage(void){ fprintf(stdout, "usage: %s", "fsx [-dnqLOW] [-b opnum] [-c Prob] [-l flen] [-m ""start:end] [-o oplen] [-p progressinterval] [-r readbdy] [-s style] [-t ""truncbdy] [-w writebdy] [-D startingop] [-N numops] [-P dirpath] [-S seed] ""[ -I random|rotate ] fname [additional paths to fname..]\n"" -b opnum: beginning operation number (default 1)\n"" -c P: 1 in P chance of file close+open at each op (default infinity)\n"" -d: debug output for all operations [-d -d = more debugging]\n"" -l flen: the upper bound on file size (default 262144)\n"" -m startop:endop: monitor (print debug output) specified byte rang""(default 0:infinity)\n"" -n: no verifications of file size\n"" -o oplen: the upper bound on operation size (default 65536)\n"" -p progressinterval: debug output at specified operation interval\n"" -q: quieter operation\n"" -r readbdy: 4096 would make reads page aligned (default 1)\n"" -s style: 1 gives smaller truncates (default 0)\n"" -t truncbdy: 4096 would make truncates page aligned (default 1)\n"" -w writebdy: 4096 would make writes page aligned (default 1)\n"" -D startingop: debug output starting at specified operation\n"" -L: fsxLite - no file creations & no file size changes\n"" -N numops: total # operations to do (default infinity)\n"" -O: use oplen (see -o flag) for every op (default random)\n"" -P: save .fsxlog and .fsxgood files in dirpath (default ./)\n"" -S seed: for random # generator (default 1) 0 gets timestamp\n"" -W: mapped write operations DISabled\n"" -R: read() system calls only (mapped reads disabled)\n"" -I: When multiple paths to the file are given each operation uses"" a different path. Iterate through them in order with 'rotate'"" or chose then at 'random'. (defaults to random)\n"" fname: this filename is REQUIRED (no default)\n"); exit(90);}intgetnum(char *s, char **e){ int ret = -1; *e = (char *) 0; ret = strtol(s, e, 0); if (*e) switch (**e) { case 'b': case 'B': ret *= 512; *e = *e + 1; break; case 'k': case 'K': ret *= 1024; *e = *e + 1; break; case 'm': case 'M': ret *= 1024*1024; *e = *e + 1; break; case 'w': case 'W': ret *= 4; *e = *e + 1; break; } return (ret);}intmain(int argc, char **argv){ int i, style, ch; char *endp; int dirpath = 0; goodfile[0] = 0; logfile[0] = 0; page_size = getpagesize(); page_mask = page_size - 1; setvbuf(stdout, (char *)0, _IOLBF, 0); /* line buffered stdout */ while ((ch = getopt(argc, argv, "b:c:dl:m:no:p:qr:s:t:w:D:I:LN:OP:RS:W")) != EOF) switch (ch) { case 'b': simulatedopcount = getnum(optarg, &endp); if (!quiet) fprintf(stdout, "Will begin at operation" "%ld\n", simulatedopcount); if (simulatedopcount == 0) usage(); simulatedopcount -= 1; break; case 'c': closeprob = getnum(optarg, &endp); if (!quiet) fprintf(stdout, "Chance of close/open is 1 in %d\n", closeprob); if (closeprob <= 0) usage(); break; case 'd': debug++; break; case 'l': maxfilelen = getnum(optarg, &endp); if (maxfilelen <= 0) usage(); break; case 'm': monitorstart = getnum(optarg, &endp); if (monitorstart < 0) usage(); if (!endp || *endp++ != ':') usage(); monitorend = getnum(endp, &endp); if (monitorend < 0) usage(); if (monitorend == 0) monitorend = -1; /* aka infinity */ debug = 1; case 'n': sizechecks = 0; break; case 'o': maxoplen = getnum(optarg, &endp); if (maxoplen <= 0) usage(); break; case 'p': progressinterval = getnum(optarg, &endp); if (progressinterval < 0) usage(); break; case 'q': quiet = 1; break; case 'r': readbdy = getnum(optarg, &endp); if (readbdy <= 0) usage(); break; case 's': style = getnum(optarg, &endp); if (style < 0 || style > 1) usage(); break; case 't': truncbdy = getnum(optarg, &endp); if (truncbdy <= 0) usage(); break; case 'w': writebdy = getnum(optarg, &endp); if (writebdy <= 0) usage(); break; case 'D': debugstart = getnum(optarg, &endp); if (debugstart < 1) usage(); break; case 'I': assign_fd_policy(optarg); break; case 'L': lite = 1; break; case 'N': numops = getnum(optarg, &endp); if (numops < 0) usage(); break; case 'O': randomoplen = 0; break; case 'P': strncpy(goodfile, optarg, sizeof(goodfile)); strcat(goodfile, "/"); strncpy(logfile, optarg, sizeof(logfile)); strcat(logfile, "/"); dirpath = 1; break; case 'R': mapped_reads = 0; break; case 'S': seed = getnum(optarg, &endp); if (seed == 0) seed = time(0) % 10000; if (!quiet) fprintf(stdout, "Seed set to %d\n", seed); if (seed < 0) usage(); break; case 'W': mapped_writes = 0; if (!quiet) fprintf(stdout, "mapped writes DISABLED\n"); break; default: usage(); /* NOTREACHED */ } argc -= optind; argv += optind; if (argc < 1) usage(); fname = argv[0]; signal(SIGHUP, cleanup); signal(SIGINT, cleanup); signal(SIGPIPE, cleanup); signal(SIGALRM, cleanup); signal(SIGTERM, cleanup); signal(SIGXCPU, cleanup); signal(SIGXFSZ, cleanup); signal(SIGVTALRM, cleanup); signal(SIGUSR1, cleanup); signal(SIGUSR2, cleanup); initstate(seed, state, 256); setstate(state); open_test_files(argv, argc); strncat(goodfile, dirpath ? my_basename(fname) : fname, 256); strcat (goodfile, ".fsxgood"); fsxgoodfd = open(goodfile, O_RDWR|O_CREAT|O_TRUNC, 0666); if (fsxgoodfd < 0) { prterr(goodfile); exit(92); } strncat(logfile, dirpath ? my_basename(fname) : fname, 256); strcat (logfile, ".fsxlog"); fsxlogf = fopen(logfile, "w"); if (fsxlogf == NULL) { prterr(logfile); exit(93); } if (lite) { off_t ret; int fd = get_fd(); file_size = maxfilelen = lseek(fd, (off_t)0, SEEK_END); if (file_size == (off_t)-1) { prterr(fname); warn("main: lseek eof"); exit(94); } ret = lseek(fd, (off_t)0, SEEK_SET); if (ret == (off_t)-1) { prterr(fname); warn("main: lseek 0"); exit(95); } } original_buf = (char *) malloc(maxfilelen); for (i = 0; i < maxfilelen; i++) original_buf[i] = random() % 256; good_buf = (char *) malloc(maxfilelen); memset(good_buf, '\0', maxfilelen); temp_buf = (char *) malloc(maxoplen); memset(temp_buf, '\0', maxoplen); if (lite) { /* zero entire existing file */ ssize_t written; int fd = get_fd(); written = write(fd, good_buf, (size_t)maxfilelen); if (written != maxfilelen) { if (written == -1) { prterr(fname); warn("main: error on write"); } else warn("main: short write, 0x%x bytes instead" "of 0x%x\n", (unsigned)written, maxfilelen); exit(98); } } else check_trunc_hack(); while (numops == -1 || numops--) test(); close_test_files(); prt("All operations completed A-OK!\n"); exit(0); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -