4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
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.
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).
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
24 * Copyright 2015 Cray Inc, all rights reserved.
27 * A few portions are extracted from llapi_layout_test.c
29 * The purpose of this test is to exert the layout swap function, with
32 * The program will exit as soon as a non zero error code is returned.
39 #include <sys/types.h>
45 #include <lustre/lustreapi.h>
47 #define ERROR(fmt, ...) \
48 fprintf(stderr, "%s: %s:%d: %s: " fmt "\n", \
49 program_invocation_short_name, __FILE__, __LINE__, \
50 __func__, ## __VA_ARGS__);
52 #define DIE(fmt, ...) \
54 ERROR(fmt, ## __VA_ARGS__); \
58 #define ASSERTF(cond, fmt, ...) \
61 DIE("assertion '%s' failed: "fmt, \
62 #cond, ## __VA_ARGS__); \
65 #define PERFORM(testfn) \
67 fprintf(stderr, "Starting test " #testfn " at %lld\n", \
68 (unsigned long long)time(NULL)); \
72 fprintf(stderr, "Finishing test " #testfn " at %lld\n", \
73 (unsigned long long)time(NULL)); \
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";
80 static char fsmountdir[PATH_MAX]; /* Lustre mountpoint */
81 static char *lustre_dir; /* Test directory inside Lustre */
83 /* Cleanup our test directory. */
84 static void cleanup(void)
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);
93 ASSERTF(rc != -1, "Cannot execute rm command");
94 ASSERTF(WEXITSTATUS(rc) == 0,
95 "rm command returned %d", WEXITSTATUS(rc));
98 /* Create a filename inside the test directory. Will assert on
100 static char *create_file_name(const char *name)
105 rc = asprintf(&filename, "%s/%s/%s", lustre_dir, maindir, name);
106 ASSERTF(rc > 0, "can't make filename for '%s'", name);
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)
120 filename = create_file_name(name);
122 fd = open(filename, O_CREAT|O_TRUNC|O_RDWR, 0600);
123 ASSERTF(fd >= 0, "open failed for '%s': %s",
124 filename, strerror(errno));
128 /* Fill-up the new file. */
129 memset(buf, c, sizeof(buf));
132 size_t to_write = size;
134 if (to_write > sizeof(buf))
135 to_write = sizeof(buf);
137 rc = write(fd, buf, to_write);
138 ASSERTF(rc > 0, "writing %zu bytes to '%s' failed: %s",
139 to_write, name, strerror(errno));
147 /* Test basic swap */
148 static void test10(void)
153 size_t foo1_size = 2000;
154 size_t foo2_size = 5000;
157 rc = mkdir(mainpath, 0);
158 ASSERTF(rc == 0, "mkdir failed for '%s': %s",
159 mainpath, strerror(errno));
161 fd1 = create_file("foo1", foo1_size, 'x');
162 fd2 = create_file("foo2", foo2_size, 'y');
164 rc = llapi_fswap_layouts(fd1, fd2, 0, 0, 0);
165 ASSERTF(rc == 0, "llapi_fswap_layouts failed: %s",
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);
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);
184 /* Test self swap. It's a no-op and will always succeed. */
185 static void test11(void)
189 size_t foo1_size = 2000;
191 rc = mkdir(mainpath, 0);
192 ASSERTF(rc == 0, "mkdir failed for '%s': %s",
193 mainpath, strerror(errno));
195 fd1 = create_file("foo1", foo1_size, 'x');
197 rc = llapi_fswap_layouts(fd1, fd1, 0, 0, 0);
198 ASSERTF(rc == 0, "llapi_fswap_layouts failed: %s",
204 /* Test self swap, on different handles. It's a no-op and will always
206 static void test12(void)
211 size_t foo1_size = 2000;
213 rc = mkdir(mainpath, 0);
214 ASSERTF(rc == 0, "mkdir failed for '%s': %s",
215 mainpath, strerror(errno));
217 fd1 = create_file("foo1", foo1_size, 'x');
219 ASSERTF(fd2 != -1, "dup failed: %s", strerror(errno));
221 rc = llapi_fswap_layouts(fd1, fd2, 0, 0, 0);
222 ASSERTF(rc == 0, "llapi_fswap_layouts failed: %s",
229 /* Swap with a non Lustre file */
230 static void test13(void)
235 size_t foo1_size = 2000;
237 rc = mkdir(mainpath, 0);
238 ASSERTF(rc == 0, "mkdir failed for '%s': %s",
239 mainpath, strerror(errno));
241 fd1 = create_file("foo1", foo1_size, 'x');
243 fd2 = open("/dev/null", O_RDWR);
244 ASSERTF(fd2 != -1, "open '/dev/null/' failed: %s", strerror(errno));
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",
255 rc = llapi_fswap_layouts(fd2, fd1, 0, 0, 0);
256 ASSERTF(rc == -ENOTTY, "llapi_fswap_layouts failed: %s",
263 /* Swap with bogus values */
264 static void test14(void)
268 rc = llapi_fswap_layouts(-6, -2, 0, 0, 0);
269 ASSERTF(rc == -EBADF, "llapi_fswap_layouts failed: %s",
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",
280 rc = llapi_fswap_layouts(456789076, 234567895, 0, 0, 0);
281 ASSERTF(rc == -EBADF, "llapi_fswap_layouts failed: %s",
285 /* Lease only test. */
286 static void test15(void)
293 rc = mkdir(mainpath, 0);
294 ASSERTF(rc == 0, "mkdir failed for '%s': %s",
295 mainpath, strerror(errno));
297 filename = create_file_name("foo1");
299 fd = create_file("foo1", 1000, 'x');
301 rc = llapi_lease_get(fd, LL_LEASE_RDLCK);
302 ASSERTF(rc == 0, "cannot get lease '%s': %s", filename, strerror(-rc));
306 /* Read lease on read file */
307 fd = open(filename, O_RDONLY);
308 ASSERTF(fd >= 0, "open failed for '%s': %s", filename, strerror(errno));
310 rc = llapi_lease_get(fd, LL_LEASE_RDLCK);
311 ASSERTF(rc == 0, "cannot get lease '%s': %s", filename, strerror(-rc));
313 rc = llapi_lease_check(fd);
314 ASSERTF(rc == LL_LEASE_RDLCK,
315 "invalid lease type on '%s': %s", filename, strerror(-rc));
319 /* Write lease on write file */
320 fd = open(filename, O_WRONLY);
321 ASSERTF(fd >= 0, "open failed for '%s': %s", filename, strerror(errno));
323 rc = llapi_lease_get(fd, LL_LEASE_WRLCK);
324 ASSERTF(rc == 0, "cannot get lease '%s': %s", filename, strerror(-rc));
326 rc = llapi_lease_check(fd);
327 ASSERTF(rc == LL_LEASE_WRLCK,
328 "invalid lease type on '%s': %s", filename, strerror(-rc));
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));
336 rc = llapi_lease_get(fd, LL_LEASE_RDLCK);
337 ASSERTF(rc == 0, "cannot get lease '%s': %s", filename, strerror(-rc));
339 rc = llapi_lease_check(fd);
340 ASSERTF(rc == LL_LEASE_RDLCK,
341 "invalid lease type on '%s': %s", filename, strerror(-rc));
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));
349 rc = llapi_lease_get(fd, LL_LEASE_WRLCK);
350 ASSERTF(rc == 0, "cannot get lease '%s': %s", filename, strerror(-rc));
352 rc = llapi_lease_check(fd);
353 ASSERTF(rc == LL_LEASE_WRLCK,
354 "invalid lease type on '%s': %s", filename, strerror(-rc));
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));
362 rc = llapi_lease_get(fd, LL_LEASE_RDLCK);
363 ASSERTF(rc == -EPERM, "cannot get lease '%s': %s",
364 filename, strerror(-rc));
366 rc = llapi_lease_check(fd);
368 "invalid lease type on '%s': %s", filename, strerror(-rc));
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));
376 rc = llapi_lease_get(fd, LL_LEASE_WRLCK);
377 ASSERTF(rc == -EPERM, "cannot get lease '%s': %s",
378 filename, strerror(-rc));
380 rc = llapi_lease_check(fd);
382 "invalid lease type on '%s': %s", filename, strerror(-rc));
386 /* Get read lease again */
387 fd = open(filename, O_RDWR);
388 ASSERTF(fd >= 0, "open failed for '%s': %s", filename, strerror(errno));
390 rc = llapi_lease_get(fd, LL_LEASE_RDLCK);
391 ASSERTF(rc == 0, "cannot get lease '%s': %s", filename, strerror(-rc));
393 rc = llapi_lease_get(fd, LL_LEASE_RDLCK);
394 ASSERTF(rc == -EBUSY, "can get lease '%s': %s",
395 filename, strerror(-rc));
397 rc = llapi_lease_check(fd);
398 ASSERTF(rc == LL_LEASE_RDLCK,
399 "invalid lease type on '%s': %s", filename, strerror(-rc));
403 /* Get write lease again */
404 fd = open(filename, O_RDWR);
405 ASSERTF(fd >= 0, "open failed for '%s': %s", filename, strerror(errno));
407 rc = llapi_lease_get(fd, LL_LEASE_WRLCK);
408 ASSERTF(rc == 0, "cannot get lease '%s': %s", filename, strerror(-rc));
410 rc = llapi_lease_get(fd, LL_LEASE_WRLCK);
411 ASSERTF(rc == -EBUSY, "can get lease '%s': %s",
412 filename, strerror(-rc));
414 rc = llapi_lease_check(fd);
415 ASSERTF(rc == LL_LEASE_WRLCK,
416 "invalid lease type on '%s': %s", filename, strerror(-rc));
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));
424 rc = llapi_lease_get(fd, LL_LEASE_RDLCK);
425 ASSERTF(rc == 0, "cannot get lease '%s': %s", filename, strerror(-rc));
427 rc = llapi_lease_check(fd);
428 ASSERTF(rc == LL_LEASE_RDLCK,
429 "invalid lease type on '%s': %s", filename, strerror(-rc));
431 rc = llapi_lease_put(fd);
432 ASSERTF(rc == LL_LEASE_RDLCK, "was not able to put back lease '%s': %s",
433 filename, strerror(-rc));
435 rc = llapi_lease_check(fd);
437 "invalid lease type on '%s': %s", filename, strerror(-rc));
439 rc = llapi_lease_get(fd, LL_LEASE_RDLCK);
440 ASSERTF(rc == 0, "cannot get lease '%s': %s", filename, strerror(-rc));
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));
448 rc = llapi_lease_get(fd, LL_LEASE_WRLCK);
449 ASSERTF(rc == 0, "cannot get lease '%s': %s", filename, strerror(-rc));
451 rc = llapi_lease_check(fd);
452 ASSERTF(rc == LL_LEASE_WRLCK,
453 "invalid lease type on '%s': %s", filename, strerror(-rc));
455 rc = llapi_lease_put(fd);
456 ASSERTF(rc == LL_LEASE_WRLCK, "was not able to put back lease '%s': %s",
457 filename, strerror(-rc));
459 rc = llapi_lease_check(fd);
461 "invalid lease type on '%s': %s", filename, strerror(-rc));
463 rc = llapi_lease_get(fd, LL_LEASE_WRLCK);
464 ASSERTF(rc == 0, "cannot get lease '%s': %s", filename, strerror(-rc));
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));
472 for (i = 0; i < 1000; i++) {
473 rc = llapi_lease_get(fd, LL_LEASE_WRLCK);
474 ASSERTF(rc == 0, "cannot get lease '%s': %s",
475 filename, strerror(-rc));
477 rc = llapi_lease_put(fd);
478 ASSERTF(rc == LL_LEASE_WRLCK,
479 "was not able to put back lease '%s': %s",
480 filename, strerror(-rc));
482 rc = llapi_lease_get(fd, LL_LEASE_RDLCK);
483 ASSERTF(rc == 0, "cannot get lease '%s': %s",
484 filename, strerror(-rc));
486 rc = llapi_lease_put(fd);
487 ASSERTF(rc == LL_LEASE_RDLCK,
488 "was not able to put back lease '%s': %s",
489 filename, strerror(-rc));
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));
498 rc = llapi_lease_get(fd, LL_LEASE_WRLCK);
499 ASSERTF(rc == 0, "cannot get lease '%s': %s", filename, strerror(-rc));
501 rc = llapi_lease_check(fd);
502 ASSERTF(rc == LL_LEASE_WRLCK,
503 "invalid lease type on '%s': %s", filename, strerror(-rc));
505 rc = llapi_lease_put(fd);
506 ASSERTF(rc == LL_LEASE_WRLCK, "was not able to put back lease '%s': %s",
507 filename, strerror(-rc));
509 rc = llapi_lease_check(fd);
511 "invalid lease type on '%s': %s", filename, strerror(-rc));
513 rc = llapi_lease_get(fd, LL_LEASE_RDLCK);
514 ASSERTF(rc == 0, "cannot get lease '%s': %s", filename, strerror(-rc));
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));
522 rc = llapi_lease_get(fd, LL_LEASE_RDLCK);
523 ASSERTF(rc == 0, "cannot get lease '%s': %s", filename, strerror(-rc));
525 rc = llapi_lease_check(fd);
526 ASSERTF(rc == LL_LEASE_RDLCK,
527 "invalid lease type on '%s': %s", filename, strerror(-rc));
529 rc = llapi_lease_put(fd);
530 ASSERTF(rc == LL_LEASE_RDLCK, "was not able to put back lease '%s': %s",
531 filename, strerror(-rc));
533 rc = llapi_lease_check(fd);
535 "invalid lease type on '%s': %s", filename, strerror(-rc));
537 rc = llapi_lease_get(fd, LL_LEASE_WRLCK);
538 ASSERTF(rc == 0, "cannot get lease '%s': %s", filename, strerror(-rc));
545 /* Lease on file opened by FID */
546 static void test16(void)
553 rc = mkdir(mainpath, 0);
554 ASSERTF(rc == 0, "mkdir failed for '%s': %s",
555 mainpath, strerror(errno));
557 filename = create_file_name("foo1");
559 fd = create_file("foo1", 1000, 'x');
561 rc = llapi_path2fid(filename, &fid);
562 ASSERTF(rc == 0, "llapi_path2fid failed for '%s': %s",
563 filename, strerror(-rc));
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));
571 rc = llapi_lease_get(fd, LL_LEASE_RDLCK);
572 ASSERTF(rc == 0, "cannot get lease '%s': %s", filename, strerror(-rc));
579 /* Lease on directories */
580 static void test17(void)
586 rc = mkdir(mainpath, 0);
587 ASSERTF(rc == 0, "mkdir failed for '%s': %s",
588 mainpath, strerror(errno));
590 fd = open(mainpath, O_DIRECTORY);
591 ASSERTF(fd >= 0, "open failed for '%s': %s", mainpath, strerror(errno));
593 rc = llapi_lease_get(fd, LL_LEASE_RDLCK);
594 ASSERTF(rc == -ENOTTY, "can get lease on directory '%s': %s",
595 mainpath, strerror(-rc));
599 /* On lustre mountpoint */
600 fd = open(fsmountdir, O_DIRECTORY);
601 ASSERTF(fd >= 0, "open failed for '%s': %s", mainpath, strerror(errno));
603 rc = llapi_lease_get(fd, LL_LEASE_RDLCK);
604 ASSERTF(rc == -ENOTTY, "can get lease on directory '%s': %s",
605 mainpath, strerror(-rc));
611 static void test20(void)
616 size_t foo1_size = 2000;
617 size_t foo2_size = 5000;
622 rc = mkdir(mainpath, 0);
623 ASSERTF(rc == 0, "mkdir failed for '%s': %s",
624 mainpath, strerror(errno));
626 fd1 = create_file("foo1", foo1_size, 'x');
627 fd2 = create_file("foo2", foo2_size, 'y');
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));
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]);
640 rc = llapi_fswap_layouts(fd1, fd2, 0, 0, 0);
641 ASSERTF(rc == 0, "llapi_fswap_layouts failed: %s",
644 /* Read from fd1. Its file pointer is now positioned inside
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]);
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);
656 /* Read from fd2. After the swap, the file pointer is past the
658 rc = read(fd2, buf, 1);
659 ASSERTF(rc == 0, "unexpected read returned rc=%d (errno %s)",
660 rc, strerror(errno));
663 ASSERTF(rc == 0, "close failed: %s", strerror(errno));
666 ASSERTF(rc == 0, "close failed: %s", strerror(errno));
669 /* Test multiple swaps between 2 files */
670 static void test30(void)
675 size_t foo1_size = 2000;
676 size_t foo2_size = 5000;
680 rc = mkdir(mainpath, 0);
681 ASSERTF(rc == 0, "mkdir failed for '%s': %s",
682 mainpath, strerror(errno));
684 fd1 = create_file("foo1", foo1_size, 'x');
685 fd2 = create_file("foo2", foo2_size, 'y');
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",
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);
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);
711 /* Test multiple swaps between 3 files */
712 static void test31(void)
718 size_t foo1_size = 2000;
719 size_t foo2_size = 5000;
720 size_t foo3_size = 8000;
725 rc = mkdir(mainpath, 0);
726 ASSERTF(rc == 0, "mkdir failed for '%s': %s",
727 mainpath, strerror(errno));
729 fd1 = create_file("foo1", foo1_size, 'x');
730 fd2 = create_file("foo2", foo2_size, 'y');
731 fd3 = create_file("foo3", foo3_size, 'z');
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",
740 rc = llapi_fswap_layouts(fd2, fd3, 0, 0, 0);
741 ASSERTF(rc == 0, "llapi_fswap_layouts failed: %s",
744 rc = llapi_fswap_layouts(fd1, fd3, 0, 0, 0);
745 ASSERTF(rc == 0, "llapi_fswap_layouts failed: %s",
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);
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);
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);
772 /* Swap with lease */
773 static void test40(void)
778 size_t foo1_size = 2000;
779 size_t foo2_size = 5000;
781 rc = mkdir(mainpath, 0);
782 ASSERTF(rc == 0, "mkdir failed for '%s': %s",
783 mainpath, strerror(errno));
785 fd1 = create_file("foo1", foo1_size, 'x');
786 fd2 = create_file("foo2", foo2_size, 'y');
788 rc = llapi_lease_get(fd1, LL_LEASE_RDLCK);
789 ASSERTF(rc == 0, "cannot get lease '%s': %s", mainpath, strerror(-rc));
791 rc = llapi_lease_check(fd1);
792 ASSERTF(rc == LL_LEASE_RDLCK,
793 "invalid lease type on '%s': %s", mainpath, strerror(-rc));
795 rc = llapi_fswap_layouts(fd1, fd2, 0, 0, SWAP_LAYOUTS_CLOSE);
796 ASSERTF(rc == 0, "llapi_fswap_layouts failed: %s",
799 rc = llapi_lease_check(fd1);
800 ASSERTF(rc == 0, "lease not lost on '%s': %s", mainpath, strerror(-rc));
802 rc = llapi_lease_put(fd1);
803 ASSERTF(rc == -ENOLCK,
804 "was able to put back lease: %s", strerror(-rc));
806 rc = llapi_lease_check(fd1);
807 ASSERTF(rc == 0, "lease not lost on '%s': %s", mainpath, strerror(-rc));
810 ASSERTF(rc == 0, "close failed: %s", strerror(errno));
813 ASSERTF(rc == 0, "close failed: %s", strerror(errno));
816 /* Swap with close but no lease */
817 static void test41(void)
822 size_t foo1_size = 2000;
823 size_t foo2_size = 5000;
825 rc = mkdir(mainpath, 0);
826 ASSERTF(rc == 0, "mkdir failed for '%s': %s",
827 mainpath, strerror(errno));
829 fd1 = create_file("foo1", foo1_size, 'x');
830 fd2 = create_file("foo2", foo2_size, 'y');
832 rc = llapi_fswap_layouts(fd1, fd2, 0, 0, SWAP_LAYOUTS_CLOSE);
833 ASSERTF(rc == -ENOLCK, "llapi_fswap_layouts failed: %s",
836 /* swap failed, so fd1 has to be closed. */
838 ASSERTF(rc == 0, "close failed: %s", strerror(errno));
841 ASSERTF(rc == 0, "close failed: %s", strerror(errno));
844 /* swap with data versions */
845 static void test42(void)
850 size_t foo1_size = 2000;
851 size_t foo2_size = 5000;
856 __u64 new_new_dv1 = 0;
857 __u64 new_new_dv2 = 0;
861 rc = mkdir(mainpath, 0);
862 ASSERTF(rc == 0, "mkdir failed for '%s': %s",
863 mainpath, strerror(errno));
865 /* Get dataversion for two files.
866 * Make sure values are different so that the following checks make
868 fd1 = create_file("foo1", foo1_size, 'x');
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");
875 fd2 = create_file("foo2", foo2_size, 'y');
877 rc = llapi_get_data_version(fd2, &dv2, LL_DV_RD_FLUSH);
878 ASSERTF(rc == 0, "cannot get dataversion for fd2: %s",
880 ASSERTF(dv2 != 0, "got dataversion 0 for fd2");
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));
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));
896 rc = llapi_fswap_layouts(fd1, fd2, 0, 0, SWAP_LAYOUTS_CHECK_DV2);
897 ASSERTF(rc == -EAGAIN, "incorrect return from swap: %s", strerror(-rc));
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));
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));
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));
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));
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));
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));
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));
933 printf("DV = %llx and %llx\n", dv1, dv2);
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));
941 /* Check dataversion. */
942 rc = llapi_get_data_version(fd1, &new_dv1, LL_DV_RD_FLUSH);
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);
948 rc = llapi_get_data_version(fd2, &new_dv2, LL_DV_RD_FLUSH);
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);
954 printf("new DV = %llx and %llx\n", new_dv1, new_dv2);
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));
965 /* Reopen the files and check again the dataversion */
966 name_fd1 = create_file_name("foo1");
967 fd1 = open(name_fd1, O_RDONLY);
969 "open failed for '%s': %s", name_fd1, strerror(errno));
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);
978 name_fd2 = create_file_name("foo2");
979 fd2 = open(name_fd2, O_RDONLY);
981 "open failed for '%s': %s", name_fd2, strerror(errno));
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);
990 printf("DV= %llx and %llx\n", new_new_dv1, new_new_dv2);
999 /* swap group lock, no group */
1000 static void test50(void)
1005 size_t foo1_size = 2000;
1006 size_t foo2_size = 5000;
1008 rc = mkdir(mainpath, 0);
1009 ASSERTF(rc == 0, "mkdir failed for '%s': %s",
1010 mainpath, strerror(errno));
1012 fd1 = create_file("foo1", foo1_size, 'x');
1013 fd2 = create_file("foo2", foo2_size, 'y');
1015 rc = llapi_fswap_layouts_grouplock(fd1, fd2, 0, 0, 0, 0);
1016 ASSERTF(rc == 0, "llapi_fswap_layouts_grouplock failed: %s",
1023 /* swap group lock, with group */
1024 static void test51(void)
1029 size_t foo1_size = 2000;
1030 size_t foo2_size = 5000;
1032 rc = mkdir(mainpath, 0);
1033 ASSERTF(rc == 0, "mkdir failed for '%s': %s",
1034 mainpath, strerror(errno));
1036 fd1 = create_file("foo1", foo1_size, 'x');
1037 fd2 = create_file("foo2", foo2_size, 'y');
1039 rc = llapi_fswap_layouts_grouplock(fd1, fd2, 0, 0, 456789, 0);
1040 ASSERTF(rc == 0, "llapi_fswap_layouts_grouplock failed: %s",
1047 /* swap group lock, with existing group locks */
1048 static void test52(void)
1053 size_t foo1_size = 2000;
1054 size_t foo2_size = 5000;
1057 rc = mkdir(mainpath, 0);
1058 ASSERTF(rc == 0, "mkdir failed for '%s': %s",
1059 mainpath, strerror(errno));
1061 fd1 = create_file("foo1", foo1_size, 'x');
1062 fd2 = create_file("foo2", foo2_size, 'y');
1064 /* lock a descriptor, but swap without */
1065 rc = llapi_group_lock(fd1, gid);
1066 ASSERTF(rc == 0, "cannot lock 'foo1': %s", strerror(-rc));
1068 rc = llapi_fswap_layouts_grouplock(fd1, fd2, 0, 0, 0, 0);
1069 ASSERTF(rc == 0, "llapi_fswap_layouts_grouplock failed: %s",
1072 rc = llapi_group_unlock(fd1, gid);
1073 ASSERTF(rc == 0, "cannot unlock 'foo1': %s", strerror(-rc));
1079 /* Swap group lock, with existing group locks, on second descriptor */
1080 static void test53(void)
1085 size_t foo1_size = 2000;
1086 size_t foo2_size = 5000;
1089 rc = mkdir(mainpath, 0);
1090 ASSERTF(rc == 0, "mkdir failed for '%s': %s",
1091 mainpath, strerror(errno));
1093 fd1 = create_file("foo1", foo1_size, 'x');
1094 fd2 = create_file("foo2", foo2_size, 'y');
1096 /* lock a descriptor, but swap without */
1097 rc = llapi_group_lock(fd2, gid);
1098 ASSERTF(rc == 0, "cannot lock 'foo1': %s", strerror(-rc));
1100 rc = llapi_fswap_layouts_grouplock(fd1, fd2, 0, 0, 0, 0);
1101 ASSERTF(rc == 0, "llapi_fswap_layouts_grouplock failed: %s",
1104 rc = llapi_group_unlock(fd2, gid);
1105 ASSERTF(rc == 0, "cannot unlock 'foo1': %s", strerror(-rc));
1111 /* swap group lock, lock a descriptor, and try to swap with it. */
1112 static void test54(void)
1117 size_t foo1_size = 2000;
1118 size_t foo2_size = 5000;
1121 rc = mkdir(mainpath, 0);
1122 ASSERTF(rc == 0, "mkdir failed for '%s': %s",
1123 mainpath, strerror(errno));
1125 fd1 = create_file("foo1", foo1_size, 'x');
1126 fd2 = create_file("foo2", foo2_size, 'y');
1129 rc = llapi_group_lock(fd1, gid);
1130 ASSERTF(rc == 0, "cannot lock 'foo1': %s", strerror(-rc));
1132 rc = llapi_fswap_layouts_grouplock(fd1, fd2, 0, 0, gid, 0);
1133 ASSERTF(rc == -EINVAL, "llapi_fswap_layouts_grouplock failed: %s",
1136 rc = llapi_group_unlock(fd1, gid);
1137 ASSERTF(rc == 0, "cannot unlock 'foo1': %s", strerror(-rc));
1143 /* Swap group lock, lock a descriptor, and try to swap with it, on
1144 * second descriptor. */
1145 static void test55(void)
1150 size_t foo1_size = 2000;
1151 size_t foo2_size = 5000;
1154 rc = mkdir(mainpath, 0);
1155 ASSERTF(rc == 0, "mkdir failed for '%s': %s",
1156 mainpath, strerror(errno));
1158 fd1 = create_file("foo1", foo1_size, 'x');
1159 fd2 = create_file("foo2", foo2_size, 'y');
1161 rc = llapi_group_lock(fd2, gid);
1162 ASSERTF(rc == 0, "cannot lock 'foo1': %s", strerror(-rc));
1164 rc = llapi_fswap_layouts_grouplock(fd1, fd2, 0, 0, gid, 0);
1165 ASSERTF(rc == -EINVAL, "llapi_fswap_layouts_grouplock failed: %s",
1168 rc = llapi_group_unlock(fd2, gid);
1169 ASSERTF(rc == 0, "cannot unlock 'foo1': %s", strerror(-rc));
1175 /* Swap group lock, lock a descriptor, and try to swap with another
1177 static void test56(void)
1182 size_t foo1_size = 2000;
1183 size_t foo2_size = 5000;
1187 rc = mkdir(mainpath, 0);
1188 ASSERTF(rc == 0, "mkdir failed for '%s': %s",
1189 mainpath, strerror(errno));
1191 fd1 = create_file("foo1", foo1_size, 'x');
1192 fd2 = create_file("foo2", foo2_size, 'y');
1194 rc = llapi_group_lock(fd1, gid1);
1195 ASSERTF(rc == 0, "cannot lock 'foo1': %s", strerror(-rc));
1197 rc = llapi_group_lock(fd2, gid2);
1198 ASSERTF(rc == 0, "cannot lock 'foo1': %s", strerror(-rc));
1200 rc = llapi_fswap_layouts_grouplock(fd1, fd2, 0, 0, 0, 0);
1201 ASSERTF(rc == 0, "llapi_fswap_layouts_grouplock failed: %s",
1204 rc = llapi_group_unlock(fd1, gid1);
1205 ASSERTF(rc == 0, "cannot unlock 'foo1': %s", strerror(-rc));
1207 rc = llapi_group_unlock(fd2, gid2);
1208 ASSERTF(rc == 0, "cannot unlock 'foo2': %s", strerror(-rc));
1214 /* Swap group lock, lock both descriptor, and try to swap with another
1216 static void test57(void)
1221 size_t foo1_size = 2000;
1222 size_t foo2_size = 5000;
1226 rc = mkdir(mainpath, 0);
1227 ASSERTF(rc == 0, "mkdir failed for '%s': %s",
1228 mainpath, strerror(errno));
1230 fd1 = create_file("foo1", foo1_size, 'x');
1231 fd2 = create_file("foo2", foo2_size, 'y');
1233 rc = llapi_group_lock(fd1, gid1);
1234 ASSERTF(rc == 0, "cannot lock 'foo1': %s", strerror(-rc));
1236 rc = llapi_group_lock(fd2, gid2);
1237 ASSERTF(rc == 0, "cannot lock 'foo1': %s", strerror(-rc));
1239 rc = llapi_fswap_layouts_grouplock(fd1, fd2, 0, 0, gid1+gid2, 0);
1240 ASSERTF(rc == -EINVAL, "llapi_fswap_layouts_grouplock failed: %s",
1243 rc = llapi_group_unlock(fd1, gid1);
1244 ASSERTF(rc == 0, "cannot unlock 'foo1': %s", strerror(-rc));
1246 rc = llapi_group_unlock(fd2, gid2);
1247 ASSERTF(rc == 0, "cannot unlock 'foo2': %s", strerror(-rc));
1253 /* Swap group lock, lock both descriptor with same gid, and try to
1255 static void test58(void)
1260 size_t foo1_size = 2000;
1261 size_t foo2_size = 5000;
1264 rc = mkdir(mainpath, 0);
1265 ASSERTF(rc == 0, "mkdir failed for '%s': %s",
1266 mainpath, strerror(errno));
1268 fd1 = create_file("foo1", foo1_size, 'x');
1269 fd2 = create_file("foo2", foo2_size, 'y');
1271 rc = llapi_group_lock(fd1, gid);
1272 ASSERTF(rc == 0, "cannot lock 'foo1': %s", strerror(-rc));
1274 rc = llapi_group_lock(fd2, gid);
1275 ASSERTF(rc == 0, "cannot lock 'foo1': %s", strerror(-rc));
1277 rc = llapi_fswap_layouts_grouplock(fd1, fd2, 0, 0, gid, 0);
1278 ASSERTF(rc == -EINVAL, "llapi_fswap_layouts_grouplock failed: %s",
1281 rc = llapi_group_unlock(fd1, gid);
1282 ASSERTF(rc == 0, "cannot unlock 'foo1': %s", strerror(-rc));
1284 rc = llapi_group_unlock(fd2, gid);
1285 ASSERTF(rc == 0, "cannot unlock 'foo2': %s", strerror(-rc));
1291 /* Swap group lock, lock both descriptor with same gid, and swap with
1293 static void test59(void)
1298 size_t foo1_size = 2000;
1299 size_t foo2_size = 5000;
1302 rc = mkdir(mainpath, 0);
1303 ASSERTF(rc == 0, "mkdir failed for '%s': %s",
1304 mainpath, strerror(errno));
1306 fd1 = create_file("foo1", foo1_size, 'x');
1307 fd2 = create_file("foo2", foo2_size, 'y');
1309 rc = llapi_group_lock(fd1, gid);
1310 ASSERTF(rc == 0, "cannot lock 'foo1': %s", strerror(-rc));
1312 rc = llapi_group_lock(fd2, gid);
1313 ASSERTF(rc == 0, "cannot lock 'foo1': %s", strerror(-rc));
1315 rc = llapi_fswap_layouts_grouplock(fd1, fd2, 0, 0, 0, 0);
1316 ASSERTF(rc == 0, "llapi_fswap_layouts_grouplock failed: %s",
1319 rc = llapi_group_unlock(fd1, gid);
1320 ASSERTF(rc == 0, "cannot unlock 'foo1': %s", strerror(-rc));
1322 rc = llapi_group_unlock(fd2, gid);
1323 ASSERTF(rc == 0, "cannot unlock 'foo2': %s", strerror(-rc));
1329 static void usage(char *prog)
1331 fprintf(stderr, "Usage: %s [-d lustre_dir]\n", prog);
1335 static void process_args(int argc, char *argv[])
1339 while ((c = getopt(argc, argv, "d:")) != -1) {
1342 lustre_dir = optarg;
1346 fprintf(stderr, "Unknown option '%c'\n", optopt);
1353 int main(int argc, char *argv[])
1358 process_args(argc, argv);
1359 if (lustre_dir == NULL)
1360 lustre_dir = "/mnt/lustre";
1362 rc = llapi_search_mounts(lustre_dir, 0, fsmountdir, fsname);
1364 fprintf(stderr, "Error: '%s': not a Lustre filesystem\n",
1366 return EXIT_FAILURE;
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);
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");
1404 return EXIT_SUCCESS;