Whamcloud - gitweb
LU-6142 tests: Fix style issues for openfile.c
[fs/lustre-release.git] / lustre / tests / swap_lock_test.c
1 /*
2  * GPL HEADER START
3  *
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 only,
8  * as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License version 2 for more details (a copy is included
14  * in the LICENSE file that accompanied this code).
15  *
16  * You should have received a copy of the GNU General Public License
17  * version 2 along with this program; If not, see
18  * http://www.gnu.org/licenses/gpl-2.0.html
19  *
20  * GPL HEADER END
21  */
22
23 /*
24  * Copyright 2015 Cray Inc, all rights reserved.
25  * Author: Frank Zago.
26  *
27  * A few portions are extracted from llapi_layout_test.c
28  *
29  * The purpose of this test is to exert the layout swap function, with
30  * locking.
31  *
32  * The program will exit as soon as a non zero error code is returned.
33  */
34
35 #include <stdlib.h>
36 #include <errno.h>
37 #include <getopt.h>
38 #include <fcntl.h>
39 #include <sys/types.h>
40 #include <sys/stat.h>
41 #include <unistd.h>
42 #include <poll.h>
43 #include <time.h>
44
45 #include <lustre/lustreapi.h>
46
47 #define ERROR(fmt, ...)                                                 \
48         fprintf(stderr, "%s: %s:%d: %s: " fmt "\n",                     \
49                 program_invocation_short_name, __FILE__, __LINE__,      \
50                 __func__, ## __VA_ARGS__);
51
52 #define DIE(fmt, ...)                           \
53         do {                                    \
54                 ERROR(fmt, ## __VA_ARGS__);     \
55                 exit(EXIT_FAILURE);             \
56         } while (0)
57
58 #define ASSERTF(cond, fmt, ...)                                         \
59         do {                                                            \
60                 if (!(cond))                                            \
61                         DIE("assertion '%s' failed: "fmt,               \
62                             #cond, ## __VA_ARGS__);                     \
63         } while (0)
64
65 #define PERFORM(testfn) \
66         do {                                                            \
67                 fprintf(stderr, "Starting test " #testfn " at %lld\n",  \
68                         (unsigned long long)time(NULL));                \
69                 cleanup();                                              \
70                 testfn();                                               \
71                 cleanup();                                              \
72                 fprintf(stderr, "Finishing test " #testfn " at %lld\n", \
73                         (unsigned long long)time(NULL));                \
74         } while (0)
75
76 /* Name of file/directory. Will be set once and will not change. */
77 static char mainpath[PATH_MAX];
78 static const char *maindir = "swap_lock_test_dir_4525654";
79
80 static char fsmountdir[PATH_MAX];       /* Lustre mountpoint */
81 static char *lustre_dir;                /* Test directory inside Lustre */
82
83 /* Cleanup our test directory. */
84 static void cleanup(void)
85 {
86         char cmd[PATH_MAX];
87         int rc;
88
89         rc = snprintf(cmd, sizeof(cmd), "rm -rf -- '%s'", mainpath);
90         ASSERTF(rc > 0 && rc < sizeof(cmd),
91                 "invalid delete command for path '%s'", mainpath);
92         rc = system(cmd);
93         ASSERTF(rc != -1, "Cannot execute rm command");
94         ASSERTF(WEXITSTATUS(rc) == 0,
95                 "rm command returned %d", WEXITSTATUS(rc));
96 }
97
98 /* Create a filename inside the test directory. Will assert on
99  * error. */
100 static char *create_file_name(const char *name)
101 {
102         char *filename;
103         int rc;
104
105         rc = asprintf(&filename, "%s/%s/%s", lustre_dir, maindir, name);
106         ASSERTF(rc > 0, "can't make filename for '%s'", name);
107
108         return filename;
109 }
110
111 /* Create a file of a given size in the test directory, filed with
112  * c. Will assert on error. */
113 int create_file(const char *name, size_t size, unsigned char c)
114 {
115         int fd;
116         char *filename;
117         int rc;
118         char buf[64*1024];
119
120         filename = create_file_name(name);
121
122         fd = open(filename, O_CREAT|O_TRUNC|O_RDWR, 0600);
123         ASSERTF(fd >= 0, "open failed for '%s': %s",
124                 filename, strerror(errno));
125
126         free(filename);
127
128         /* Fill-up the new file. */
129         memset(buf, c, sizeof(buf));
130
131         while (size) {
132                 size_t to_write = size;
133
134                 if (to_write > sizeof(buf))
135                         to_write = sizeof(buf);
136
137                 rc = write(fd, buf, to_write);
138                 ASSERTF(rc > 0, "writing %zu bytes to '%s' failed: %s",
139                         to_write, name, strerror(errno));
140
141                 size -= to_write;
142         }
143
144         return fd;
145 }
146
147 /* Test basic swap */
148 static void test10(void)
149 {
150         int rc;
151         int fd1;
152         int fd2;
153         size_t foo1_size = 2000;
154         size_t foo2_size = 5000;
155         struct stat stbuf;
156
157         rc = mkdir(mainpath, 0);
158         ASSERTF(rc == 0, "mkdir failed for '%s': %s",
159                 mainpath, strerror(errno));
160
161         fd1 = create_file("foo1", foo1_size, 'x');
162         fd2 = create_file("foo2", foo2_size, 'y');
163
164         rc = llapi_fswap_layouts(fd1, fd2, 0, 0, 0);
165         ASSERTF(rc == 0, "llapi_fswap_layouts failed: %s",
166                 strerror(-rc));
167
168         rc = fstat(fd1, &stbuf);
169         ASSERTF(rc == 0, "stat failed on 'foo1': %s", strerror(errno));
170         ASSERTF(stbuf.st_size == foo2_size,
171                 "invalid size found: %llu instead of %zu",
172                 (unsigned long long)stbuf.st_size, foo2_size);
173
174         rc = fstat(fd2, &stbuf);
175         ASSERTF(rc == 0, "stat failed on 'foo2': %s", strerror(errno));
176         ASSERTF(stbuf.st_size == foo1_size,
177                 "invalid size found: %llu instead of %zu",
178                 (unsigned long long)stbuf.st_size, foo1_size);
179
180         close(fd1);
181         close(fd2);
182 }
183
184 /* Test self swap. It's a no-op and will always succeed. */
185 static void test11(void)
186 {
187         int rc;
188         int fd1;
189         size_t foo1_size = 2000;
190
191         rc = mkdir(mainpath, 0);
192         ASSERTF(rc == 0, "mkdir failed for '%s': %s",
193                 mainpath, strerror(errno));
194
195         fd1 = create_file("foo1", foo1_size, 'x');
196
197         rc = llapi_fswap_layouts(fd1, fd1, 0, 0, 0);
198         ASSERTF(rc == 0, "llapi_fswap_layouts failed: %s",
199                 strerror(-rc));
200
201         close(fd1);
202 }
203
204 /* Test self swap, on different handles. It's a no-op and will always
205  * succeed. */
206 static void test12(void)
207 {
208         int rc;
209         int fd1;
210         int fd2;
211         size_t foo1_size = 2000;
212
213         rc = mkdir(mainpath, 0);
214         ASSERTF(rc == 0, "mkdir failed for '%s': %s",
215                 mainpath, strerror(errno));
216
217         fd1 = create_file("foo1", foo1_size, 'x');
218         fd2 = dup(fd1);
219         ASSERTF(fd2 != -1, "dup failed:  %s", strerror(errno));
220
221         rc = llapi_fswap_layouts(fd1, fd2, 0, 0, 0);
222         ASSERTF(rc == 0, "llapi_fswap_layouts failed: %s",
223                 strerror(-rc));
224
225         close(fd1);
226         close(fd2);
227 }
228
229 /* Swap with a non Lustre file */
230 static void test13(void)
231 {
232         int rc;
233         int fd1;
234         int fd2;
235         size_t foo1_size = 2000;
236
237         rc = mkdir(mainpath, 0);
238         ASSERTF(rc == 0, "mkdir failed for '%s': %s",
239                 mainpath, strerror(errno));
240
241         fd1 = create_file("foo1", foo1_size, 'x');
242
243         fd2 = open("/dev/null", O_RDWR);
244         ASSERTF(fd2 != -1, "open '/dev/null/' failed:  %s", strerror(errno));
245
246         /* Note that the returned error will be different for both
247          * operations. In the first swap, fd1 is on Lustre, so the
248          * ioctl will succeed, but its processing will eventually fail
249          * because fd2 is not on Lustre. In the second swap, the ioctl
250          * request is unknown, so ioctl() will directly fail. */
251         rc = llapi_fswap_layouts(fd1, fd2, 0, 0, 0);
252         ASSERTF(rc == -EINVAL, "llapi_fswap_layouts failed: %s",
253                 strerror(-rc));
254
255         rc = llapi_fswap_layouts(fd2, fd1, 0, 0, 0);
256         ASSERTF(rc == -ENOTTY, "llapi_fswap_layouts failed: %s",
257                 strerror(-rc));
258
259         close(fd1);
260         close(fd2);
261 }
262
263 /* Swap with bogus values */
264 static void test14(void)
265 {
266         int rc;
267
268         rc = llapi_fswap_layouts(-6, -2, 0, 0, 0);
269         ASSERTF(rc == -EBADF, "llapi_fswap_layouts failed: %s",
270                 strerror(-rc));
271
272         /* When run under a shell, rc is -EINVAL. When run under
273          * Lustre test suite, stdin is redirected, and rc is
274          * -ENOTTY. Catch both cases. */
275         rc = llapi_fswap_layouts(0, 0, 0, 0, 0);
276         ASSERTF(rc == -EINVAL || rc == -ENOTTY,
277                 "llapi_fswap_layouts failed: %s",
278                 strerror(-rc));
279
280         rc = llapi_fswap_layouts(456789076, 234567895, 0, 0, 0);
281         ASSERTF(rc == -EBADF, "llapi_fswap_layouts failed: %s",
282                 strerror(-rc));
283 }
284
285 /* Lease only test. */
286 static void test15(void)
287 {
288         int rc;
289         char *filename;
290         int fd;
291         int i;
292
293         rc = mkdir(mainpath, 0);
294         ASSERTF(rc == 0, "mkdir failed for '%s': %s",
295                 mainpath, strerror(errno));
296
297         filename = create_file_name("foo1");
298
299         fd = create_file("foo1", 1000, 'x');
300
301         rc = llapi_lease_acquire(fd, LL_LEASE_RDLCK);
302         ASSERTF(rc == 0, "cannot get lease '%s': %s", filename, strerror(-rc));
303
304         close(fd);
305
306         /* Read lease on read file */
307         fd = open(filename, O_RDONLY);
308         ASSERTF(fd >= 0, "open failed for '%s': %s", filename, strerror(errno));
309
310         rc = llapi_lease_acquire(fd, LL_LEASE_RDLCK);
311         ASSERTF(rc == 0, "cannot get lease '%s': %s", filename, strerror(-rc));
312
313         rc = llapi_lease_check(fd);
314         ASSERTF(rc == LL_LEASE_RDLCK,
315                 "invalid lease type on '%s': %s", filename, strerror(-rc));
316
317         close(fd);
318
319         /* Write lease on write file */
320         fd = open(filename, O_WRONLY);
321         ASSERTF(fd >= 0, "open failed for '%s': %s", filename, strerror(errno));
322
323         rc = llapi_lease_acquire(fd, LL_LEASE_WRLCK);
324         ASSERTF(rc == 0, "cannot get lease '%s': %s", filename, strerror(-rc));
325
326         rc = llapi_lease_check(fd);
327         ASSERTF(rc == LL_LEASE_WRLCK,
328                 "invalid lease type on '%s': %s", filename, strerror(-rc));
329
330         close(fd);
331
332         /* Read lease on read/write file */
333         fd = open(filename, O_RDWR);
334         ASSERTF(fd >= 0, "open failed for '%s': %s", filename, strerror(errno));
335
336         rc = llapi_lease_acquire(fd, LL_LEASE_RDLCK);
337         ASSERTF(rc == 0, "cannot get lease '%s': %s", filename, strerror(-rc));
338
339         rc = llapi_lease_check(fd);
340         ASSERTF(rc == LL_LEASE_RDLCK,
341                 "invalid lease type on '%s': %s", filename, strerror(-rc));
342
343         close(fd);
344
345         /* Write lease on read/write file */
346         fd = open(filename, O_RDWR);
347         ASSERTF(fd >= 0, "open failed for '%s': %s", filename, strerror(errno));
348
349         rc = llapi_lease_acquire(fd, LL_LEASE_WRLCK);
350         ASSERTF(rc == 0, "cannot get lease '%s': %s", filename, strerror(-rc));
351
352         rc = llapi_lease_check(fd);
353         ASSERTF(rc == LL_LEASE_WRLCK,
354                 "invalid lease type on '%s': %s", filename, strerror(-rc));
355
356         close(fd);
357
358         /* Read lease on write only file */
359         fd = open(filename, O_WRONLY);
360         ASSERTF(fd >= 0, "open failed for '%s': %s", filename, strerror(errno));
361
362         rc = llapi_lease_acquire(fd, LL_LEASE_RDLCK);
363         ASSERTF(rc == -EPERM, "cannot get lease '%s': %s",
364                 filename, strerror(-rc));
365
366         rc = llapi_lease_check(fd);
367         ASSERTF(rc == 0,
368                 "invalid lease type on '%s': %s", filename, strerror(-rc));
369
370         close(fd);
371
372         /* Write lease on read only file */
373         fd = open(filename, O_RDONLY);
374         ASSERTF(fd >= 0, "open failed for '%s': %s", filename, strerror(errno));
375
376         rc = llapi_lease_acquire(fd, LL_LEASE_WRLCK);
377         ASSERTF(rc == -EPERM, "cannot get lease '%s': %s",
378                 filename, strerror(-rc));
379
380         rc = llapi_lease_check(fd);
381         ASSERTF(rc == 0,
382                 "invalid lease type on '%s': %s", filename, strerror(-rc));
383
384         close(fd);
385
386         /* Get read lease again */
387         fd = open(filename, O_RDWR);
388         ASSERTF(fd >= 0, "open failed for '%s': %s", filename, strerror(errno));
389
390         rc = llapi_lease_acquire(fd, LL_LEASE_RDLCK);
391         ASSERTF(rc == 0, "cannot get lease '%s': %s", filename, strerror(-rc));
392
393         rc = llapi_lease_acquire(fd, LL_LEASE_RDLCK);
394         ASSERTF(rc == -EBUSY, "can get lease '%s': %s",
395                 filename, strerror(-rc));
396
397         rc = llapi_lease_check(fd);
398         ASSERTF(rc == LL_LEASE_RDLCK,
399                 "invalid lease type on '%s': %s", filename, strerror(-rc));
400
401         close(fd);
402
403         /* Get write lease again */
404         fd = open(filename, O_RDWR);
405         ASSERTF(fd >= 0, "open failed for '%s': %s", filename, strerror(errno));
406
407         rc = llapi_lease_acquire(fd, LL_LEASE_WRLCK);
408         ASSERTF(rc == 0, "cannot get lease '%s': %s", filename, strerror(-rc));
409
410         rc = llapi_lease_acquire(fd, LL_LEASE_WRLCK);
411         ASSERTF(rc == -EBUSY, "can get lease '%s': %s",
412                 filename, strerror(-rc));
413
414         rc = llapi_lease_check(fd);
415         ASSERTF(rc == LL_LEASE_WRLCK,
416                 "invalid lease type on '%s': %s", filename, strerror(-rc));
417
418         close(fd);
419
420         /* Get a lease, release and get again */
421         fd = open(filename, O_RDWR);
422         ASSERTF(fd >= 0, "open failed for '%s': %s", filename, strerror(errno));
423
424         rc = llapi_lease_acquire(fd, LL_LEASE_RDLCK);
425         ASSERTF(rc == 0, "cannot get lease '%s': %s", filename, strerror(-rc));
426
427         rc = llapi_lease_check(fd);
428         ASSERTF(rc == LL_LEASE_RDLCK,
429                 "invalid lease type on '%s': %s", filename, strerror(-rc));
430
431         rc = llapi_lease_release(fd);
432         ASSERTF(rc == LL_LEASE_RDLCK, "was not able to put back lease '%s': %s",
433                 filename, strerror(-rc));
434
435         rc = llapi_lease_check(fd);
436         ASSERTF(rc == 0,
437                 "invalid lease type on '%s': %s", filename, strerror(-rc));
438
439         rc = llapi_lease_acquire(fd, LL_LEASE_RDLCK);
440         ASSERTF(rc == 0, "cannot get lease '%s': %s", filename, strerror(-rc));
441
442         close(fd);
443
444         /* Get a write lease, release and get again */
445         fd = open(filename, O_RDWR);
446         ASSERTF(fd >= 0, "open failed for '%s': %s", filename, strerror(errno));
447
448         rc = llapi_lease_acquire(fd, LL_LEASE_WRLCK);
449         ASSERTF(rc == 0, "cannot get lease '%s': %s", filename, strerror(-rc));
450
451         rc = llapi_lease_check(fd);
452         ASSERTF(rc == LL_LEASE_WRLCK,
453                 "invalid lease type on '%s': %s", filename, strerror(-rc));
454
455         rc = llapi_lease_release(fd);
456         ASSERTF(rc == LL_LEASE_WRLCK, "was not able to put back lease '%s': %s",
457                 filename, strerror(-rc));
458
459         rc = llapi_lease_check(fd);
460         ASSERTF(rc == 0,
461                 "invalid lease type on '%s': %s", filename, strerror(-rc));
462
463         rc = llapi_lease_acquire(fd, LL_LEASE_WRLCK);
464         ASSERTF(rc == 0, "cannot get lease '%s': %s", filename, strerror(-rc));
465
466         close(fd);
467
468         /* Get and put lease in a loop */
469         fd = open(filename, O_RDWR);
470         ASSERTF(fd >= 0, "open failed for '%s': %s", filename, strerror(errno));
471
472         for (i = 0; i < 1000; i++) {
473                 rc = llapi_lease_acquire(fd, LL_LEASE_WRLCK);
474                 ASSERTF(rc == 0, "cannot get lease '%s': %s",
475                         filename, strerror(-rc));
476
477                 rc = llapi_lease_release(fd);
478                 ASSERTF(rc == LL_LEASE_WRLCK,
479                         "was not able to put back lease '%s': %s",
480                         filename, strerror(-rc));
481
482                 rc = llapi_lease_acquire(fd, LL_LEASE_RDLCK);
483                 ASSERTF(rc == 0, "cannot get lease '%s': %s",
484                         filename, strerror(-rc));
485
486                 rc = llapi_lease_release(fd);
487                 ASSERTF(rc == LL_LEASE_RDLCK,
488                         "was not able to put back lease '%s': %s",
489                         filename, strerror(-rc));
490         }
491
492         close(fd);
493
494         /* Get a write lease, release and take a read one */
495         fd = open(filename, O_RDWR);
496         ASSERTF(fd >= 0, "open failed for '%s': %s", filename, strerror(errno));
497
498         rc = llapi_lease_acquire(fd, LL_LEASE_WRLCK);
499         ASSERTF(rc == 0, "cannot get lease '%s': %s", filename, strerror(-rc));
500
501         rc = llapi_lease_check(fd);
502         ASSERTF(rc == LL_LEASE_WRLCK,
503                 "invalid lease type on '%s': %s", filename, strerror(-rc));
504
505         rc = llapi_lease_release(fd);
506         ASSERTF(rc == LL_LEASE_WRLCK, "was not able to put back lease '%s': %s",
507                 filename, strerror(-rc));
508
509         rc = llapi_lease_check(fd);
510         ASSERTF(rc == 0,
511                 "invalid lease type on '%s': %s", filename, strerror(-rc));
512
513         rc = llapi_lease_acquire(fd, LL_LEASE_RDLCK);
514         ASSERTF(rc == 0, "cannot get lease '%s': %s", filename, strerror(-rc));
515
516         close(fd);
517
518         /* Get a read lease, release and take a write one */
519         fd = open(filename, O_RDWR);
520         ASSERTF(fd >= 0, "open failed for '%s': %s", filename, strerror(errno));
521
522         rc = llapi_lease_acquire(fd, LL_LEASE_RDLCK);
523         ASSERTF(rc == 0, "cannot get lease '%s': %s", filename, strerror(-rc));
524
525         rc = llapi_lease_check(fd);
526         ASSERTF(rc == LL_LEASE_RDLCK,
527                 "invalid lease type on '%s': %s", filename, strerror(-rc));
528
529         rc = llapi_lease_release(fd);
530         ASSERTF(rc == LL_LEASE_RDLCK, "was not able to put back lease '%s': %s",
531                 filename, strerror(-rc));
532
533         rc = llapi_lease_check(fd);
534         ASSERTF(rc == 0,
535                 "invalid lease type on '%s': %s", filename, strerror(-rc));
536
537         rc = llapi_lease_acquire(fd, LL_LEASE_WRLCK);
538         ASSERTF(rc == 0, "cannot get lease '%s': %s", filename, strerror(-rc));
539
540         close(fd);
541
542         free(filename);
543 }
544
545 /* Lease on file opened by FID */
546 static void test16(void)
547 {
548         int rc;
549         char *filename;
550         int fd;
551         struct lu_fid fid;
552
553         rc = mkdir(mainpath, 0);
554         ASSERTF(rc == 0, "mkdir failed for '%s': %s",
555                 mainpath, strerror(errno));
556
557         filename = create_file_name("foo1");
558
559         fd = create_file("foo1", 1000, 'x');
560
561         rc = llapi_path2fid(filename, &fid);
562         ASSERTF(rc == 0, "llapi_path2fid failed for '%s': %s",
563                 filename, strerror(-rc));
564
565         close(fd);
566
567         fd = llapi_open_by_fid(fsmountdir, &fid,
568                                O_RDWR | O_NOATIME | O_NONBLOCK | O_NOFOLLOW);
569         ASSERTF(fd >= 0, "open failed for '%s': %s", filename, strerror(errno));
570
571         rc = llapi_lease_acquire(fd, LL_LEASE_RDLCK);
572         ASSERTF(rc == 0, "cannot get lease '%s': %s", filename, strerror(-rc));
573
574         close(fd);
575
576         free(filename);
577 }
578
579 /* Lease on directories */
580 static void test17(void)
581 {
582         int rc;
583         int fd;
584
585         /* On a directory */
586         rc = mkdir(mainpath, 0);
587         ASSERTF(rc == 0, "mkdir failed for '%s': %s",
588                 mainpath, strerror(errno));
589
590         fd = open(mainpath, O_DIRECTORY);
591         ASSERTF(fd >= 0, "open failed for '%s': %s", mainpath, strerror(errno));
592
593         rc = llapi_lease_acquire(fd, LL_LEASE_RDLCK);
594         ASSERTF(rc == -ENOTTY, "can get lease on directory '%s': %s",
595                 mainpath, strerror(-rc));
596
597         close(fd);
598
599         /* On lustre mountpoint */
600         fd = open(fsmountdir, O_DIRECTORY);
601         ASSERTF(fd >= 0, "open failed for '%s': %s", mainpath, strerror(errno));
602
603         rc = llapi_lease_acquire(fd, LL_LEASE_RDLCK);
604         ASSERTF(rc == -ENOTTY, "can get lease on directory '%s': %s",
605                 mainpath, strerror(-rc));
606
607         close(fd);
608 }
609
610 /* Read then swap */
611 static void test20(void)
612 {
613         int rc;
614         int fd1;
615         int fd2;
616         size_t foo1_size = 2000;
617         size_t foo2_size = 5000;
618         char buf[100];
619         off_t offset;
620         struct stat stbuf;
621
622         rc = mkdir(mainpath, 0);
623         ASSERTF(rc == 0, "mkdir failed for '%s': %s",
624                 mainpath, strerror(errno));
625
626         fd1 = create_file("foo1", foo1_size, 'x');
627         fd2 = create_file("foo2", foo2_size, 'y');
628
629         /* foo2 is bigger than foo1. Read a byte in foo2, past foo1_size. */
630         offset = lseek(fd2, foo1_size + 100, SEEK_SET);
631         ASSERTF(offset == foo1_size + 100, "lseek to pos %zu failed: %s",
632                 foo1_size + 100, strerror(errno));
633
634         rc = read(fd2, buf, 1);
635         ASSERTF(rc == 1, "read 1 byte on foo2 failed: %s, rc=%d",
636                 strerror(errno), rc);
637         ASSERTF(buf[0] == 'y', "invalid data found on foo2: %x", buf[0]);
638
639         /* Now swap */
640         rc = llapi_fswap_layouts(fd1, fd2, 0, 0, 0);
641         ASSERTF(rc == 0, "llapi_fswap_layouts failed: %s",
642                 strerror(-rc));
643
644         /* Read from fd1. Its file pointer is now positioned inside
645          * the new data. */
646         rc = read(fd1, buf, 1);
647         ASSERTF(rc == 1, "read 1 byte on foo1 failed: %s", strerror(errno));
648         ASSERTF(buf[0] == 'y', "invalid data found on foo2: %x", buf[0]);
649
650         rc = fstat(fd2, &stbuf);
651         ASSERTF(rc == 0, "stat failed on 'foo2': %s", strerror(errno));
652         ASSERTF(stbuf.st_size == foo1_size,
653                 "invalid size found: %llu instead of %zu",
654                 (unsigned long long)stbuf.st_size, foo1_size);
655
656         /* Read from fd2. After the swap, the file pointer is past the
657          * data. */
658         rc = read(fd2, buf, 1);
659         ASSERTF(rc == 0, "unexpected read returned rc=%d (errno %s)",
660                 rc, strerror(errno));
661
662         rc = close(fd1);
663         ASSERTF(rc == 0, "close failed: %s", strerror(errno));
664
665         rc = close(fd2);
666         ASSERTF(rc == 0, "close failed: %s", strerror(errno));
667 }
668
669 /* Test multiple swaps between 2 files */
670 static void test30(void)
671 {
672         int rc;
673         int fd1;
674         int fd2;
675         size_t foo1_size = 2000;
676         size_t foo2_size = 5000;
677         int i;
678         struct stat stbuf;
679
680         rc = mkdir(mainpath, 0);
681         ASSERTF(rc == 0, "mkdir failed for '%s': %s",
682                 mainpath, strerror(errno));
683
684         fd1 = create_file("foo1", foo1_size, 'x');
685         fd2 = create_file("foo2", foo2_size, 'y');
686
687         for (i = 0; i < 1000; i++) {
688                 rc = llapi_fswap_layouts(fd1, fd2, 0, 0, 0);
689                 ASSERTF(rc == 0, "llapi_fswap_layouts failed: %s",
690                         strerror(-rc));
691
692                 rc = fstat(fd1, &stbuf);
693                 ASSERTF(rc == 0, "stat failed on 'foo1': %s", strerror(errno));
694                 ASSERTF(stbuf.st_size == i % 2 ? foo2_size : foo1_size,
695                         "invalid size found: %llu instead of %zu",
696                         (unsigned long long)stbuf.st_size,
697                         i % 2 ? foo2_size : foo1_size);
698
699                 rc = fstat(fd2, &stbuf);
700                 ASSERTF(rc == 0, "stat failed on 'foo2': %s", strerror(errno));
701                 ASSERTF(stbuf.st_size == i % 2 ? foo1_size : foo2_size,
702                         "invalid size found: %llu instead of %zu",
703                         (unsigned long long)stbuf.st_size,
704                         i % 2 ? foo1_size : foo2_size);
705         }
706
707         close(fd1);
708         close(fd2);
709 }
710
711 /* Test multiple swaps between 3 files */
712 static void test31(void)
713 {
714         int rc;
715         int fd1;
716         int fd2;
717         int fd3;
718         size_t foo1_size = 2000;
719         size_t foo2_size = 5000;
720         size_t foo3_size = 8000;
721         int i;
722         struct stat stbuf;
723
724
725         rc = mkdir(mainpath, 0);
726         ASSERTF(rc == 0, "mkdir failed for '%s': %s",
727                 mainpath, strerror(errno));
728
729         fd1 = create_file("foo1", foo1_size, 'x');
730         fd2 = create_file("foo2", foo2_size, 'y');
731         fd3 = create_file("foo3", foo3_size, 'z');
732
733         /* Note: swapping 3 fd this way will be back to original
734          * layouts every 2 loops. */
735         for (i = 0; i < 999; i++) {
736                 rc = llapi_fswap_layouts(fd1, fd2, 0, 0, 0);
737                 ASSERTF(rc == 0, "llapi_fswap_layouts failed: %s",
738                         strerror(-rc));
739
740                 rc = llapi_fswap_layouts(fd2, fd3, 0, 0, 0);
741                 ASSERTF(rc == 0, "llapi_fswap_layouts failed: %s",
742                         strerror(-rc));
743
744                 rc = llapi_fswap_layouts(fd1, fd3, 0, 0, 0);
745                 ASSERTF(rc == 0, "llapi_fswap_layouts failed: %s",
746                         strerror(-rc));
747         }
748
749         rc = fstat(fd1, &stbuf);
750         ASSERTF(rc == 0, "stat failed on 'foo2': %s", strerror(errno));
751         ASSERTF(stbuf.st_size == foo1_size,
752                 "invalid size found: %llu instead of %zu",
753                 (unsigned long long)stbuf.st_size, foo1_size);
754
755         rc = fstat(fd2, &stbuf);
756         ASSERTF(rc == 0, "stat failed on 'foo2': %s", strerror(errno));
757         ASSERTF(stbuf.st_size == foo3_size,
758                 "invalid size found: %llu instead of %zu",
759                 (unsigned long long)stbuf.st_size, foo3_size);
760
761         rc = fstat(fd3, &stbuf);
762         ASSERTF(rc == 0, "stat failed on 'foo2': %s", strerror(errno));
763         ASSERTF(stbuf.st_size == foo2_size,
764                 "invalid size found: %llu instead of %zu",
765                 (unsigned long long)stbuf.st_size, foo2_size);
766
767         close(fd1);
768         close(fd2);
769         close(fd3);
770 }
771
772 /* Swap with lease */
773 static void test40(void)
774 {
775         int rc;
776         int fd1;
777         int fd2;
778         size_t foo1_size = 2000;
779         size_t foo2_size = 5000;
780
781         rc = mkdir(mainpath, 0);
782         ASSERTF(rc == 0, "mkdir failed for '%s': %s",
783                 mainpath, strerror(errno));
784
785         fd1 = create_file("foo1", foo1_size, 'x');
786         fd2 = create_file("foo2", foo2_size, 'y');
787
788         rc = llapi_lease_acquire(fd1, LL_LEASE_RDLCK);
789         ASSERTF(rc == 0, "cannot get lease '%s': %s", mainpath, strerror(-rc));
790
791         rc = llapi_lease_check(fd1);
792         ASSERTF(rc == LL_LEASE_RDLCK,
793                 "invalid lease type on '%s': %s", mainpath, strerror(-rc));
794
795         rc = llapi_fswap_layouts(fd1, fd2, 0, 0, SWAP_LAYOUTS_CLOSE);
796         ASSERTF(rc == 0, "llapi_fswap_layouts failed: %s",
797                 strerror(-rc));
798
799         rc = llapi_lease_check(fd1);
800         ASSERTF(rc == 0, "lease not lost on '%s': %s", mainpath, strerror(-rc));
801
802         rc = llapi_lease_release(fd1);
803         ASSERTF(rc == -ENOLCK,
804                 "was able to put back lease: %s", strerror(-rc));
805
806         rc = llapi_lease_check(fd1);
807         ASSERTF(rc == 0, "lease not lost on '%s': %s", mainpath, strerror(-rc));
808
809         rc = close(fd1);
810         ASSERTF(rc == 0, "close failed: %s", strerror(errno));
811
812         rc = close(fd2);
813         ASSERTF(rc == 0, "close failed: %s", strerror(errno));
814 }
815
816 /* Swap with close but no lease */
817 static void test41(void)
818 {
819         int rc;
820         int fd1;
821         int fd2;
822         size_t foo1_size = 2000;
823         size_t foo2_size = 5000;
824
825         rc = mkdir(mainpath, 0);
826         ASSERTF(rc == 0, "mkdir failed for '%s': %s",
827                 mainpath, strerror(errno));
828
829         fd1 = create_file("foo1", foo1_size, 'x');
830         fd2 = create_file("foo2", foo2_size, 'y');
831
832         rc = llapi_fswap_layouts(fd1, fd2, 0, 0, SWAP_LAYOUTS_CLOSE);
833         ASSERTF(rc == -ENOLCK, "llapi_fswap_layouts failed: %s",
834                 strerror(-rc));
835
836         /* swap failed, so fd1 has to be closed. */
837         rc = close(fd1);
838         ASSERTF(rc == 0, "close failed: %s", strerror(errno));
839
840         rc = close(fd2);
841         ASSERTF(rc == 0, "close failed: %s", strerror(errno));
842 }
843
844 /* swap with data versions */
845 static void test42(void)
846 {
847         int rc;
848         int fd1;
849         int fd2;
850         size_t foo1_size = 2000;
851         size_t foo2_size = 5000;
852         __u64 dv1 = 0;
853         __u64 dv2 = 0;
854         __u64 new_dv1 = 0;
855         __u64 new_dv2 = 0;
856         __u64 new_new_dv1 = 0;
857         __u64 new_new_dv2 = 0;
858         char *name_fd1;
859         char *name_fd2;
860
861         rc = mkdir(mainpath, 0);
862         ASSERTF(rc == 0, "mkdir failed for '%s': %s",
863                 mainpath, strerror(errno));
864
865         /* Get dataversion for two files.
866          * Make sure values are different so that the following checks make
867          * sense. */
868         fd1 = create_file("foo1", foo1_size, 'x');
869
870         rc = llapi_get_data_version(fd1, &dv1, LL_DV_RD_FLUSH);
871         ASSERTF(rc == 0, "cannot get dataversion for fd1: %s", strerror(-rc));
872         ASSERTF(dv1 != 0, "got dataversion 0 for fd1");
873
874         for (;;) {
875                 fd2 = create_file("foo2", foo2_size, 'y');
876
877                 rc = llapi_get_data_version(fd2, &dv2, LL_DV_RD_FLUSH);
878                 ASSERTF(rc == 0, "cannot get dataversion for fd2: %s",
879                         strerror(-rc));
880                 ASSERTF(dv2 != 0, "got dataversion 0 for fd2");
881
882                 if (dv1 != dv2)
883                         break;
884
885                 close(fd2);
886         }
887
888         /* swaps that should fail */
889         rc = llapi_fswap_layouts(fd1, fd2, 0, 0, SWAP_LAYOUTS_CHECK_DV1);
890         ASSERTF(rc == -EAGAIN, "incorrect return from swap: %s", strerror(-rc));
891
892         rc = llapi_fswap_layouts(fd1, fd2, dv1 + 456789, 0,
893                                  SWAP_LAYOUTS_CHECK_DV1);
894         ASSERTF(rc == -EAGAIN, "incorrect return from swap: %s", strerror(-rc));
895
896         rc = llapi_fswap_layouts(fd1, fd2, 0, 0, SWAP_LAYOUTS_CHECK_DV2);
897         ASSERTF(rc == -EAGAIN, "incorrect return from swap: %s", strerror(-rc));
898
899         rc = llapi_fswap_layouts(fd1, fd2, 0, dv2 + 987654,
900                                  SWAP_LAYOUTS_CHECK_DV2);
901         ASSERTF(rc == -EAGAIN, "incorrect return from swap: %s", strerror(-rc));
902
903         rc = llapi_fswap_layouts(fd1, fd2, 0, 0,
904                                  SWAP_LAYOUTS_CHECK_DV1 |
905                                  SWAP_LAYOUTS_CHECK_DV2);
906         ASSERTF(rc == -EAGAIN, "incorrect return from swap: %s", strerror(-rc));
907
908         rc = llapi_fswap_layouts(fd1, fd2, dv1 + 456789, 0,
909                                  SWAP_LAYOUTS_CHECK_DV1 |
910                                  SWAP_LAYOUTS_CHECK_DV2);
911         ASSERTF(rc == -EAGAIN, "incorrect return from swap: %s", strerror(-rc));
912
913         rc = llapi_fswap_layouts(fd1, fd2, dv1 + 456789, dv2 + 987654,
914                                  SWAP_LAYOUTS_CHECK_DV1 |
915                                  SWAP_LAYOUTS_CHECK_DV2);
916         ASSERTF(rc == -EAGAIN, "incorrect return from swap: %s", strerror(-rc));
917
918         rc = llapi_fswap_layouts(fd1, fd2, dv1, 0,
919                                  SWAP_LAYOUTS_CHECK_DV1 |
920                                  SWAP_LAYOUTS_CHECK_DV2);
921         ASSERTF(rc == -EAGAIN, "incorrect return from swap: %s", strerror(-rc));
922
923         rc = llapi_fswap_layouts(fd1, fd2, 0, dv2,
924                                  SWAP_LAYOUTS_CHECK_DV1 |
925                                  SWAP_LAYOUTS_CHECK_DV2);
926         ASSERTF(rc == -EAGAIN, "incorrect return from swap: %s", strerror(-rc));
927
928         rc = llapi_fswap_layouts(fd1, fd2, dv1, dv2 + 567,
929                                  SWAP_LAYOUTS_CHECK_DV1 |
930                                  SWAP_LAYOUTS_CHECK_DV2);
931         ASSERTF(rc == -EAGAIN, "incorrect return from swap: %s", strerror(-rc));
932
933         printf("DV = %llx and %llx\n", dv1, dv2);
934
935         /* Finally, a good swap */
936         rc = llapi_fswap_layouts(fd1, fd2, dv1, dv2,
937                                  SWAP_LAYOUTS_CHECK_DV1 |
938                                  SWAP_LAYOUTS_CHECK_DV2);
939         ASSERTF(rc == 0, "incorrect return from swap: %s", strerror(-rc));
940
941         /* Check dataversion. */
942         rc = llapi_get_data_version(fd1, &new_dv1, LL_DV_RD_FLUSH);
943         ASSERTF(rc == 0,
944                 "cannot get new dataversion for fd1: %s", strerror(-rc));
945         ASSERTF(dv1 != 0, "got dataversion 0 for fd1");
946         ASSERTF(dv1 != new_dv1, "got identical dataversion for fd1: %llx", dv1);
947
948         rc = llapi_get_data_version(fd2, &new_dv2, LL_DV_RD_FLUSH);
949         ASSERTF(rc == 0,
950                 "cannot get new dataversion for fd2: %s", strerror(-rc));
951         ASSERTF(dv2 != 0, "got dataversion 0 for fd2");
952         ASSERTF(dv2 != new_dv2, "got identical dataversion for fd2: %llx", dv1);
953
954         printf("new DV = %llx and %llx\n", new_dv1, new_dv2);
955
956         /* Try again with same parameters. */
957         rc = llapi_fswap_layouts(fd1, fd2, dv1, dv2,
958                                  SWAP_LAYOUTS_CHECK_DV1 |
959                                  SWAP_LAYOUTS_CHECK_DV2);
960         ASSERTF(rc == -EAGAIN, "incorrect return from swap: %s", strerror(-rc));
961
962         close(fd1);
963         close(fd2);
964
965         /* Reopen the files and check again the dataversion */
966         name_fd1 = create_file_name("foo1");
967         fd1 = open(name_fd1, O_RDONLY);
968         ASSERTF(fd1 >= 0,
969                 "open failed for '%s': %s", name_fd1, strerror(errno));
970
971         rc = llapi_get_data_version(fd1, &new_new_dv1, LL_DV_RD_FLUSH);
972         ASSERTF(rc == 0, "cannot get dataversion for fd1: %s", strerror(-rc));
973         ASSERTF(new_new_dv1 != 0, "got dataversion 0 for fd1");
974         ASSERTF(new_dv1 == new_new_dv1,
975                 "dataversion changed after re-opening: %llx and %llx",
976                 new_dv1, new_new_dv1);
977
978         name_fd2 = create_file_name("foo2");
979         fd2 = open(name_fd2, O_RDONLY);
980         ASSERTF(fd2 >= 0,
981                 "open failed for '%s': %s", name_fd2, strerror(errno));
982
983         rc = llapi_get_data_version(fd2, &new_new_dv2, LL_DV_RD_FLUSH);
984         ASSERTF(rc == 0, "cannot get dataversion for fd2: %s", strerror(-rc));
985         ASSERTF(new_new_dv2 != 0, "got dataversion 0 for fd2");
986         ASSERTF(new_dv2 == new_new_dv2,
987                 "dataversion changed after re-opening: %llx and %llx",
988                 new_dv2, new_new_dv2);
989
990         printf("DV= %llx and %llx\n", new_new_dv1, new_new_dv2);
991
992         close(fd1);
993         close(fd2);
994
995         free(name_fd1);
996         free(name_fd2);
997 }
998
999 /* swap group lock, no group */
1000 static void test50(void)
1001 {
1002         int rc;
1003         int fd1;
1004         int fd2;
1005         size_t foo1_size = 2000;
1006         size_t foo2_size = 5000;
1007
1008         rc = mkdir(mainpath, 0);
1009         ASSERTF(rc == 0, "mkdir failed for '%s': %s",
1010                 mainpath, strerror(errno));
1011
1012         fd1 = create_file("foo1", foo1_size, 'x');
1013         fd2 = create_file("foo2", foo2_size, 'y');
1014
1015         rc = llapi_fswap_layouts_grouplock(fd1, fd2, 0, 0, 0, 0);
1016         ASSERTF(rc == 0, "llapi_fswap_layouts_grouplock failed: %s",
1017                 strerror(-rc));
1018
1019         close(fd1);
1020         close(fd2);
1021 }
1022
1023 /* swap group lock, with group */
1024 static void test51(void)
1025 {
1026         int rc;
1027         int fd1;
1028         int fd2;
1029         size_t foo1_size = 2000;
1030         size_t foo2_size = 5000;
1031
1032         rc = mkdir(mainpath, 0);
1033         ASSERTF(rc == 0, "mkdir failed for '%s': %s",
1034                 mainpath, strerror(errno));
1035
1036         fd1 = create_file("foo1", foo1_size, 'x');
1037         fd2 = create_file("foo2", foo2_size, 'y');
1038
1039         rc = llapi_fswap_layouts_grouplock(fd1, fd2, 0, 0, 456789, 0);
1040         ASSERTF(rc == 0, "llapi_fswap_layouts_grouplock failed: %s",
1041                 strerror(-rc));
1042
1043         close(fd1);
1044         close(fd2);
1045 }
1046
1047 /* swap group lock, with existing group locks */
1048 static void test52(void)
1049 {
1050         int rc;
1051         int fd1;
1052         int fd2;
1053         size_t foo1_size = 2000;
1054         size_t foo2_size = 5000;
1055         int gid = 7356;
1056
1057         rc = mkdir(mainpath, 0);
1058         ASSERTF(rc == 0, "mkdir failed for '%s': %s",
1059                 mainpath, strerror(errno));
1060
1061         fd1 = create_file("foo1", foo1_size, 'x');
1062         fd2 = create_file("foo2", foo2_size, 'y');
1063
1064         /* lock a descriptor, but swap without */
1065         rc = llapi_group_lock(fd1, gid);
1066         ASSERTF(rc == 0, "cannot lock 'foo1': %s", strerror(-rc));
1067
1068         rc = llapi_fswap_layouts_grouplock(fd1, fd2, 0, 0, 0, 0);
1069         ASSERTF(rc == 0, "llapi_fswap_layouts_grouplock failed: %s",
1070                 strerror(-rc));
1071
1072         rc = llapi_group_unlock(fd1, gid);
1073         ASSERTF(rc == 0, "cannot unlock 'foo1': %s", strerror(-rc));
1074
1075         close(fd1);
1076         close(fd2);
1077 }
1078
1079 /* Swap group lock, with existing group locks, on second descriptor */
1080 static void test53(void)
1081 {
1082         int rc;
1083         int fd1;
1084         int fd2;
1085         size_t foo1_size = 2000;
1086         size_t foo2_size = 5000;
1087         int gid = 7356;
1088
1089         rc = mkdir(mainpath, 0);
1090         ASSERTF(rc == 0, "mkdir failed for '%s': %s",
1091                 mainpath, strerror(errno));
1092
1093         fd1 = create_file("foo1", foo1_size, 'x');
1094         fd2 = create_file("foo2", foo2_size, 'y');
1095
1096         /* lock a descriptor, but swap without */
1097         rc = llapi_group_lock(fd2, gid);
1098         ASSERTF(rc == 0, "cannot lock 'foo1': %s", strerror(-rc));
1099
1100         rc = llapi_fswap_layouts_grouplock(fd1, fd2, 0, 0, 0, 0);
1101         ASSERTF(rc == 0, "llapi_fswap_layouts_grouplock failed: %s",
1102                 strerror(-rc));
1103
1104         rc = llapi_group_unlock(fd2, gid);
1105         ASSERTF(rc == 0, "cannot unlock 'foo1': %s", strerror(-rc));
1106
1107         close(fd1);
1108         close(fd2);
1109 }
1110
1111 /* swap group lock, lock a descriptor, and try to swap with it. */
1112 static void test54(void)
1113 {
1114         int rc;
1115         int fd1;
1116         int fd2;
1117         size_t foo1_size = 2000;
1118         size_t foo2_size = 5000;
1119         int gid;
1120
1121         rc = mkdir(mainpath, 0);
1122         ASSERTF(rc == 0, "mkdir failed for '%s': %s",
1123                 mainpath, strerror(errno));
1124
1125         fd1 = create_file("foo1", foo1_size, 'x');
1126         fd2 = create_file("foo2", foo2_size, 'y');
1127
1128         gid = 7356;
1129         rc = llapi_group_lock(fd1, gid);
1130         ASSERTF(rc == 0, "cannot lock 'foo1': %s", strerror(-rc));
1131
1132         rc = llapi_fswap_layouts_grouplock(fd1, fd2, 0, 0, gid, 0);
1133         ASSERTF(rc == -EINVAL, "llapi_fswap_layouts_grouplock failed: %s",
1134                 strerror(-rc));
1135
1136         rc = llapi_group_unlock(fd1, gid);
1137         ASSERTF(rc == 0, "cannot unlock 'foo1': %s", strerror(-rc));
1138
1139         close(fd1);
1140         close(fd2);
1141 }
1142
1143 /* Swap group lock, lock a descriptor, and try to swap with it, on
1144  * second descriptor. */
1145 static void test55(void)
1146 {
1147         int rc;
1148         int fd1;
1149         int fd2;
1150         size_t foo1_size = 2000;
1151         size_t foo2_size = 5000;
1152         int gid = 7356;
1153
1154         rc = mkdir(mainpath, 0);
1155         ASSERTF(rc == 0, "mkdir failed for '%s': %s",
1156                 mainpath, strerror(errno));
1157
1158         fd1 = create_file("foo1", foo1_size, 'x');
1159         fd2 = create_file("foo2", foo2_size, 'y');
1160
1161         rc = llapi_group_lock(fd2, gid);
1162         ASSERTF(rc == 0, "cannot lock 'foo1': %s", strerror(-rc));
1163
1164         rc = llapi_fswap_layouts_grouplock(fd1, fd2, 0, 0, gid, 0);
1165         ASSERTF(rc == -EINVAL, "llapi_fswap_layouts_grouplock failed: %s",
1166                 strerror(-rc));
1167
1168         rc = llapi_group_unlock(fd2, gid);
1169         ASSERTF(rc == 0, "cannot unlock 'foo1': %s", strerror(-rc));
1170
1171         close(fd1);
1172         close(fd2);
1173 }
1174
1175 /* Swap group lock, lock a descriptor, and try to swap with another
1176  * one. */
1177 static void test56(void)
1178 {
1179         int rc;
1180         int fd1;
1181         int fd2;
1182         size_t foo1_size = 2000;
1183         size_t foo2_size = 5000;
1184         int gid1 = 78976;
1185         int gid2 = 3458;
1186
1187         rc = mkdir(mainpath, 0);
1188         ASSERTF(rc == 0, "mkdir failed for '%s': %s",
1189                 mainpath, strerror(errno));
1190
1191         fd1 = create_file("foo1", foo1_size, 'x');
1192         fd2 = create_file("foo2", foo2_size, 'y');
1193
1194         rc = llapi_group_lock(fd1, gid1);
1195         ASSERTF(rc == 0, "cannot lock 'foo1': %s", strerror(-rc));
1196
1197         rc = llapi_group_lock(fd2, gid2);
1198         ASSERTF(rc == 0, "cannot lock 'foo1': %s", strerror(-rc));
1199
1200         rc = llapi_fswap_layouts_grouplock(fd1, fd2, 0, 0, 0, 0);
1201         ASSERTF(rc == 0, "llapi_fswap_layouts_grouplock failed: %s",
1202                 strerror(-rc));
1203
1204         rc = llapi_group_unlock(fd1, gid1);
1205         ASSERTF(rc == 0, "cannot unlock 'foo1': %s", strerror(-rc));
1206
1207         rc = llapi_group_unlock(fd2, gid2);
1208         ASSERTF(rc == 0, "cannot unlock 'foo2': %s", strerror(-rc));
1209
1210         close(fd1);
1211         close(fd2);
1212 }
1213
1214 /* Swap group lock, lock both descriptor, and try to swap with another
1215  * one. */
1216 static void test57(void)
1217 {
1218         int rc;
1219         int fd1;
1220         int fd2;
1221         size_t foo1_size = 2000;
1222         size_t foo2_size = 5000;
1223         int gid1 = 78976;
1224         int gid2 = 3458;
1225
1226         rc = mkdir(mainpath, 0);
1227         ASSERTF(rc == 0, "mkdir failed for '%s': %s",
1228                 mainpath, strerror(errno));
1229
1230         fd1 = create_file("foo1", foo1_size, 'x');
1231         fd2 = create_file("foo2", foo2_size, 'y');
1232
1233         rc = llapi_group_lock(fd1, gid1);
1234         ASSERTF(rc == 0, "cannot lock 'foo1': %s", strerror(-rc));
1235
1236         rc = llapi_group_lock(fd2, gid2);
1237         ASSERTF(rc == 0, "cannot lock 'foo1': %s", strerror(-rc));
1238
1239         rc = llapi_fswap_layouts_grouplock(fd1, fd2, 0, 0, gid1+gid2, 0);
1240         ASSERTF(rc == -EINVAL, "llapi_fswap_layouts_grouplock failed: %s",
1241                 strerror(-rc));
1242
1243         rc = llapi_group_unlock(fd1, gid1);
1244         ASSERTF(rc == 0, "cannot unlock 'foo1': %s", strerror(-rc));
1245
1246         rc = llapi_group_unlock(fd2, gid2);
1247         ASSERTF(rc == 0, "cannot unlock 'foo2': %s", strerror(-rc));
1248
1249         close(fd1);
1250         close(fd2);
1251 }
1252
1253 /* Swap group lock, lock both descriptor with same gid, and try to
1254  * swap with it. */
1255 static void test58(void)
1256 {
1257         int rc;
1258         int fd1;
1259         int fd2;
1260         size_t foo1_size = 2000;
1261         size_t foo2_size = 5000;
1262         int gid = 6458907;
1263
1264         rc = mkdir(mainpath, 0);
1265         ASSERTF(rc == 0, "mkdir failed for '%s': %s",
1266                 mainpath, strerror(errno));
1267
1268         fd1 = create_file("foo1", foo1_size, 'x');
1269         fd2 = create_file("foo2", foo2_size, 'y');
1270
1271         rc = llapi_group_lock(fd1, gid);
1272         ASSERTF(rc == 0, "cannot lock 'foo1': %s", strerror(-rc));
1273
1274         rc = llapi_group_lock(fd2, gid);
1275         ASSERTF(rc == 0, "cannot lock 'foo1': %s", strerror(-rc));
1276
1277         rc = llapi_fswap_layouts_grouplock(fd1, fd2, 0, 0, gid, 0);
1278         ASSERTF(rc == -EINVAL, "llapi_fswap_layouts_grouplock failed: %s",
1279                 strerror(-rc));
1280
1281         rc = llapi_group_unlock(fd1, gid);
1282         ASSERTF(rc == 0, "cannot unlock 'foo1': %s", strerror(-rc));
1283
1284         rc = llapi_group_unlock(fd2, gid);
1285         ASSERTF(rc == 0, "cannot unlock 'foo2': %s", strerror(-rc));
1286
1287         close(fd1);
1288         close(fd2);
1289 }
1290
1291 /* Swap group lock, lock both descriptor with same gid, and swap with
1292  * none. */
1293 static void test59(void)
1294 {
1295         int rc;
1296         int fd1;
1297         int fd2;
1298         size_t foo1_size = 2000;
1299         size_t foo2_size = 5000;
1300         int gid = 6458907;
1301
1302         rc = mkdir(mainpath, 0);
1303         ASSERTF(rc == 0, "mkdir failed for '%s': %s",
1304                 mainpath, strerror(errno));
1305
1306         fd1 = create_file("foo1", foo1_size, 'x');
1307         fd2 = create_file("foo2", foo2_size, 'y');
1308
1309         rc = llapi_group_lock(fd1, gid);
1310         ASSERTF(rc == 0, "cannot lock 'foo1': %s", strerror(-rc));
1311
1312         rc = llapi_group_lock(fd2, gid);
1313         ASSERTF(rc == 0, "cannot lock 'foo1': %s", strerror(-rc));
1314
1315         rc = llapi_fswap_layouts_grouplock(fd1, fd2, 0, 0, 0, 0);
1316         ASSERTF(rc == 0, "llapi_fswap_layouts_grouplock failed: %s",
1317                 strerror(-rc));
1318
1319         rc = llapi_group_unlock(fd1, gid);
1320         ASSERTF(rc == 0, "cannot unlock 'foo1': %s", strerror(-rc));
1321
1322         rc = llapi_group_unlock(fd2, gid);
1323         ASSERTF(rc == 0, "cannot unlock 'foo2': %s", strerror(-rc));
1324
1325         close(fd1);
1326         close(fd2);
1327 }
1328
1329 static void usage(char *prog)
1330 {
1331         fprintf(stderr, "Usage: %s [-d lustre_dir]\n", prog);
1332         exit(EXIT_FAILURE);
1333 }
1334
1335 static void process_args(int argc, char *argv[])
1336 {
1337         int c;
1338
1339         while ((c = getopt(argc, argv, "d:")) != -1) {
1340                 switch (c) {
1341                 case 'd':
1342                         lustre_dir = optarg;
1343                         break;
1344                 case '?':
1345                 default:
1346                         fprintf(stderr, "Unknown option '%c'\n", optopt);
1347                         usage(argv[0]);
1348                         break;
1349                 }
1350         }
1351 }
1352
1353 int main(int argc, char *argv[])
1354 {
1355         char fsname[8 + 1];
1356         int rc;
1357
1358         process_args(argc, argv);
1359         if (lustre_dir == NULL)
1360                 lustre_dir = "/mnt/lustre";
1361
1362         rc = llapi_search_mounts(lustre_dir, 0, fsmountdir, fsname);
1363         if (rc != 0) {
1364                 fprintf(stderr, "Error: '%s': not a Lustre filesystem\n",
1365                         lustre_dir);
1366                 return EXIT_FAILURE;
1367         }
1368
1369         /* Play nice with Lustre test scripts. Non-line buffered output
1370          * stream under I/O redirection may appear incorrectly. */
1371         setvbuf(stdout, NULL, _IOLBF, 0);
1372
1373         /* Create a test filename and reuse it. Remove possibly old files. */
1374         rc = snprintf(mainpath, sizeof(mainpath), "%s/%s", lustre_dir, maindir);
1375         ASSERTF(rc > 0 && rc < sizeof(mainpath), "invalid name for mainpath");
1376
1377         atexit(cleanup);
1378
1379         PERFORM(test10);
1380         PERFORM(test11);
1381         PERFORM(test12);
1382         PERFORM(test13);
1383         PERFORM(test14);
1384         PERFORM(test15);
1385         PERFORM(test16);
1386         PERFORM(test17);
1387         PERFORM(test20);
1388         PERFORM(test30);
1389         PERFORM(test31);
1390         PERFORM(test40);
1391         PERFORM(test41);
1392         PERFORM(test42);
1393         PERFORM(test50);
1394         PERFORM(test51);
1395         PERFORM(test52);
1396         PERFORM(test53);
1397         PERFORM(test54);
1398         PERFORM(test55);
1399         PERFORM(test56);
1400         PERFORM(test57);
1401         PERFORM(test58);
1402         PERFORM(test59);
1403
1404         return EXIT_SUCCESS;
1405 }