14 * Usage: rw_seq_cst_vs_drop_caches /mnt/lustre/file0 /mnt/lustre2/file0
16 * Race reads of the same file on two client mounts vs writes and drop
17 * caches to detect sequential consistency violations. Run
18 * indefinately. all abort() if a consistency violation is found in
19 * which case the wait status ($?) will be 134.
22 #define handle_error(msg) \
23 do { perror(msg); exit(EXIT_FAILURE); } while (0)
25 static int fd[2] = { -1, -1 };
26 /* u_max is total number of writes, which are time consumg because they are
27 * contending with constant reads
29 static uint64_t u, u_max = UINT64_MAX / 2;
32 static void *access_thread_start(void *unused)
38 for (i = 0; i < 2; i++) {
39 rc = pread(fd[i], &v[i], sizeof(v[i]), 0);
40 if (rc < 0 || rc != sizeof(v[i]))
41 handle_error("pread");
43 } while (v[0] <= v[1]);
45 fprintf(stderr, "error: u = %"PRIu64", v = %"PRIu64", %"PRIu64"\n",
51 static char stderr_buf[4096];
53 int main(int argc, char *argv[])
55 int drop_caches_fd = -1;
56 pthread_t access_thread;
61 setvbuf(stderr, stderr_buf, _IOLBF, sizeof(stderr_buf));
64 fprintf(stderr, "Usage: %s /mnt/lustre/file0 /mnt/lustre2/file0\n", argv[0]);
68 drop_caches_fd = open("/proc/sys/vm/drop_caches", O_WRONLY);
69 assert(!(drop_caches_fd < 0));
71 for (i = 0; i < 2; i++) {
72 fd[i] = open(argv[i + 1], O_RDWR|O_CREAT|O_TRUNC, 0666);
76 rc = fstat(fd[i], &st[i]);
78 handle_error("fstat");
81 /* file0 and file1 should be the same file on two different
82 * client mount points. */
83 if (st[0].st_dev != st[1].st_dev ||
84 st[0].st_ino != st[1].st_ino) {
85 fprintf(stderr, "file mismatch\n");
89 rc = pwrite(fd[0], &u, sizeof(u), 0);
90 if (rc < 0 || rc != sizeof(u))
91 handle_error("pwrite");
93 rc = pthread_create(&access_thread, NULL, &access_thread_start, NULL);
95 handle_error("pthread_create");
97 for (u = 1; u <= u_max; u++) {
98 rc = pwrite(fd[0], &u, sizeof(u), 0);
99 if (rc < 0 || rc != sizeof(u))
100 handle_error("pwrite");
102 rc = write(drop_caches_fd, "3\n", 2);
103 if (rc < 0 || rc != 2)
104 handle_error("drop caches");
107 rc = pthread_cancel(access_thread);
109 handle_error("pthread_cancel");
111 rc = pthread_join(access_thread, NULL);
113 handle_error("pthread_join");