-
Notifications
You must be signed in to change notification settings - Fork 34
Expand file tree
/
Copy pathopen_multi.c
More file actions
191 lines (157 loc) · 4.57 KB
/
Copy pathopen_multi.c
File metadata and controls
191 lines (157 loc) · 4.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include "t/lib/tap.h"
#include "t/lib/testutil.h"
#include "mpi.h"
#include "unifyfs.h"
#define all_ok(condition, comm, ...) \
do { \
int input = (int) condition; \
int output; \
MPI_Allreduce(&input, &output, 1, MPI_INT, MPI_LAND, comm); \
int rank; \
MPI_Comm_rank(comm, &rank); \
if (rank == 0) { \
ok_at_loc(__FILE__, __LINE__, output, __VA_ARGS__, NULL); \
} \
} while (0)
int mpi_sum(int val)
{
int sum;
MPI_Allreduce(&val, &sum, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
return sum;
}
off_t getsize(char* file)
{
off_t size = (off_t)-1;
struct stat buf;
int rc = stat(file, &buf);
if (rc == 0) {
size = buf.st_size;
}
return size;
}
int main(int argc, char* argv[])
{
char mountpoint[] = "/unifyfs";
MPI_Init(&argc, &argv);
int rank, ranks;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &ranks);
unifyfs_mount(mountpoint, rank, ranks, 0);
char file[256];
sprintf(file, "%s/testfile", mountpoint);
size_t bufsize = 1024*1024;
char* buf = (char*) malloc(bufsize);
memset(buf, rank, bufsize);
MPI_Barrier(MPI_COMM_WORLD);
/* create a file in exclusive mode,
* one rank should win, all others should get EEXIST */
errno = 0;
int success = 0;
int eexist = 0;
int fd = open(file, O_WRONLY | O_CREAT | O_EXCL, 0700);
if (fd >= 0) {
success = 1;
close(fd);
} else if (errno == EEXIST) {
eexist = 1;
}
/* one rank should win */
int sum = mpi_sum(success);
all_ok(sum == 1, MPI_COMM_WORLD,
"More than one process opened file in exclusive mode");
/* all others should get EEXIST */
sum = mpi_sum(eexist);
all_ok(sum == (ranks - 1), MPI_COMM_WORLD,
"All but one process should get EEXIST when opening file in exclusive mode");
/* all delete,
* one rank should win, all others should get ENOENT */
errno = 0;
success = 0;
int enoent = 0;
int rc = unlink(file);
if (rc == 0) {
success = 1;
} else if (errno == ENOENT) {
enoent = 1;
}
/* one winner */
sum = mpi_sum(success);
all_ok(sum == 1, MPI_COMM_WORLD,
"More than one process got success on unlink of the same file");
/* everyone else should get ENOENT */
sum = mpi_sum(enoent);
all_ok(sum == (ranks - 1), MPI_COMM_WORLD,
"All but one process should get ENOENT when unlinking the same file");
/* all create, this time not exclusive */
errno = 0;
success = 0;
fd = open(file, O_WRONLY | O_CREAT | O_TRUNC, 0700);
if (fd >= 0) {
success = 1;
close(fd);
}
/* all should succeed */
all_ok(success, MPI_COMM_WORLD,
"All processes should open file with O_CREAT and not O_EXCL");
/* open file for writing */
errno = 0;
success = 0;
fd = open(file, O_WRONLY);
if (fd >= 0) {
success = 1;
close(fd);
}
/* all should succeeed */
all_ok(success, MPI_COMM_WORLD,
"All processes should open file with O_CREAT for writing");
MPI_Barrier(MPI_COMM_WORLD);
unlink(file);
MPI_Barrier(MPI_COMM_WORLD);
/* have all ranks write to a different section of the file,
* then open file with truncate on one rank to verify size change */
success = 0;
fd = open(file, O_WRONLY | O_CREAT, 0700);
if (fd >= 0) {
success = 1;
off_t offset = (off_t) (rank * bufsize);
ssize_t nwritten = pwrite(fd, buf, bufsize, offset);
if (nwritten != bufsize) {
success = 0;
}
fsync(fd);
close(fd);
}
MPI_Barrier(MPI_COMM_WORLD);
if (rank == 0) {
/* all ranks should have written some data */
off_t size = getsize(file);
ok(size == bufsize * ranks,
"File size %lu does not match expected size %lu",
size, bufsize * ranks);
/* create file with truncate */
fd = open(file, O_WRONLY | O_CREAT | O_TRUNC, 0700);
if (fd >= 0) {
close(fd);
}
/* now file should be 0 length again */
size = getsize(file);
ok(size == 0,
"File size %lu does not match expected size %lu",
size, 0);
}
MPI_Barrier(MPI_COMM_WORLD);
unlink(file);
MPI_Barrier(MPI_COMM_WORLD);
free(buf);
unifyfs_unmount();
MPI_Finalize();
return 0;
}