xv6, line by line
user/logstress.c

user/logstress.c

C · 48 lines · annotated 100% · user program / library · upstream

About this file

logstress keeps the file system’s write-ahead log busy. For every file name on its command line it starts one child process, and all children append 2000-byte chunks to their own files at the same time. Each chunk is one file-system operation (one begin_op … end_op); overlapping operations are committed together as one transaction, so the log is always busy with several at once.

Its main use is the crash test in test-xv6.py (test-xv6.py:131), added with this program in commit fe989da (“Checkpoint WIP: a crash test”, August 2025): run logstress f0 f1 f2 f3 f4 f5, kill QEMU after two seconds, boot again, and check that the kernel printed recovering tail … lines, meaning that initlog found a committed transaction in the log and replayed it (kernel/log.c:74). Whether the kill lands in a commit depends on timing, so the script retries up to 20 times; when it does, the next boot replays about a dozen blocks.

Two bugs, both checked at this commit:

  • buf holds 500 bytes, but the program fills and writes 2000 (see line 31).
  • Each child tries to write 250 × 2000 = 500,000 bytes, but the largest xv6 file is MAXFILE × BSIZE = 268 × 1024 = 274,432 bytes. Run to completion, every child fails (line 33). The crash test never runs long enough to notice.

Read before: kernel/log.c and filewrite. Read next: test-xv6.py.

6// Stress xv6 logging system by having several processes writing
7// concurrently to their own file (e.g., logstress f1 f2 f3 f4)
9#define BUFSZ 500
11char buf[BUFSZ];
13int
14main(int argc, char **argv)
16 int fd, n;
17 enum { N = 250, SZ = 2000 };
19 for (int i = 1; i < argc; i++) {
20 int pid1 = fork();
21 if (pid1 < 0) {
22 printf("%s: fork failed\n", argv[0]);
23 exit(1);
24 }
25 if (pid1 == 0) {
27 if (fd < 0) {
28 printf("%s: create %s failed\n", argv[0], argv[i]);
29 exit(1);
30 }
31 memset(buf, '0' + i, SZ);
32 for (i = 0; i < N; i++) {
33 if ((n = write(fd, buf, SZ)) != SZ) {
34 printf("write failed %d\n", n);
35 exit(1);
36 }
37 }
38 exit(0);
39 }
40 }
41 int xstatus;
42 for (int i = 1; i < argc; i++) {
44 if (xstatus != 0)
46 }
47 return 0;