Whamcloud - gitweb
LU-10994 test: remove netdisk from obdfilter-survey
[fs/lustre-release.git] / lustre / tests / rw_seq_cst_vs_drop_caches.c
1 #include <stdio.h>
2 #include <stdint.h>
3 #include <stdlib.h>
4 #include <assert.h>
5 #include <fcntl.h>
6 #include <inttypes.h>
7 #include <string.h>
8 #include <unistd.h>
9 #include <sys/mman.h>
10 #include <sys/stat.h>
11 #include <pthread.h>
12
13 /*
14  * Usage: rw_seq_cst_vs_drop_caches /mnt/lustre/file0 /mnt/lustre2/file0
15
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.
20 */
21
22 #define handle_error(msg)       \
23         do { perror(msg); exit(EXIT_FAILURE); } while (0)
24
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
28  */
29 static uint64_t u, u_max = UINT64_MAX / 2;
30 static uint64_t v[2];
31
32 static void *access_thread_start(void *unused)
33 {
34         ssize_t rc;
35         int i;
36
37         do {
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");
42                 }
43         } while (v[0] <= v[1]);
44
45         fprintf(stderr, "error: u = %"PRIu64", v = %"PRIu64", %"PRIu64"\n",
46                 u, v[0], v[1]);
47
48         abort();
49 }
50
51 static char stderr_buf[4096];
52
53 int main(int argc, char *argv[])
54 {
55         int drop_caches_fd = -1;
56         pthread_t access_thread;
57         struct stat st[2];
58         ssize_t rc;
59         int i;
60
61         setvbuf(stderr, stderr_buf, _IOLBF, sizeof(stderr_buf));
62
63         if (argc != 3) {
64                 fprintf(stderr, "Usage: %s /mnt/lustre/file0 /mnt/lustre2/file0\n", argv[0]);
65                 exit(EXIT_FAILURE);
66         }
67
68         drop_caches_fd = open("/proc/sys/vm/drop_caches", O_WRONLY);
69         assert(!(drop_caches_fd < 0));
70
71         for (i = 0; i < 2; i++) {
72                 fd[i] = open(argv[i + 1], O_RDWR|O_CREAT|O_TRUNC, 0666);
73                 if (fd[i] < 0)
74                         handle_error("open");
75
76                 rc = fstat(fd[i], &st[i]);
77                 if (rc < 0)
78                         handle_error("fstat");
79         }
80
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");
86                 exit(EXIT_FAILURE);
87         }
88
89         rc = pwrite(fd[0], &u, sizeof(u), 0);
90         if (rc < 0 || rc != sizeof(u))
91                 handle_error("pwrite");
92
93         rc = pthread_create(&access_thread, NULL, &access_thread_start, NULL);
94         if (rc != 0)
95                 handle_error("pthread_create");
96
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");
101
102                 rc = write(drop_caches_fd, "3\n", 2);
103                 if (rc < 0 || rc != 2)
104                         handle_error("drop caches");
105         }
106
107         rc = pthread_cancel(access_thread);
108         if (rc != 0)
109                 handle_error("pthread_cancel");
110
111         rc = pthread_join(access_thread, NULL);
112         if (rc != 0)
113                 handle_error("pthread_join");
114
115         return 0;
116 }