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