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 error. */
99 static char *create_file_name(const char *name)
104 rc = asprintf(&filename, "%s/%s/%s", lustre_dir, maindir, name);
105 ASSERTF(rc > 0, "can't make filename for '%s'", name);
110 /* Create a file of a given size in the test directory, filed with
111 * character 'c'. Will assert on error.
113 static 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. Is a no-op and will always succeed. */
205 static void test12(void)
210 size_t foo1_size = 2000;
212 rc = mkdir(mainpath, 0);
213 ASSERTF(rc == 0, "mkdir failed for '%s': %s",
214 mainpath, strerror(errno));
216 fd1 = create_file("foo1", foo1_size, 'x');
218 ASSERTF(fd2 != -1, "dup failed: %s", strerror(errno));
220 rc = llapi_fswap_layouts(fd1, fd2, 0, 0, 0);
221 ASSERTF(rc == 0, "llapi_fswap_layouts failed: %s",
228 /* Swap with a non Lustre file */
229 static void test13(void)
234 size_t foo1_size = 2000;
236 rc = mkdir(mainpath, 0);
237 ASSERTF(rc == 0, "mkdir failed for '%s': %s",
238 mainpath, strerror(errno));
240 fd1 = create_file("foo1", foo1_size, 'x');
242 fd2 = open("/dev/null", O_RDWR);
243 ASSERTF(fd2 != -1, "open '/dev/null/' failed: %s", strerror(errno));
245 /* Note that the returned error will be different for both
246 * operations. In the first swap, fd1 is on Lustre, so the
247 * ioctl will succeed, but its processing will eventually fail
248 * because fd2 is not on Lustre. In the second swap, the ioctl
249 * 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 Lustre test
273 * suite, stdin is redirected, and rc is -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_acquire(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_acquire(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_acquire(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_acquire(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_acquire(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_acquire(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_acquire(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_acquire(fd, LL_LEASE_RDLCK);
391 ASSERTF(rc == 0, "cannot get lease '%s': %s", filename, strerror(-rc));
393 rc = llapi_lease_acquire(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_acquire(fd, LL_LEASE_WRLCK);
408 ASSERTF(rc == 0, "cannot get lease '%s': %s", filename, strerror(-rc));
410 rc = llapi_lease_acquire(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_acquire(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_release(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_acquire(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_acquire(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_release(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_acquire(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_acquire(fd, LL_LEASE_WRLCK);
474 ASSERTF(rc == 0, "cannot get lease '%s': %s",
475 filename, strerror(-rc));
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));
482 rc = llapi_lease_acquire(fd, LL_LEASE_RDLCK);
483 ASSERTF(rc == 0, "cannot get lease '%s': %s",
484 filename, strerror(-rc));
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));
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_acquire(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_release(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_acquire(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_acquire(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_release(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_acquire(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_acquire(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_acquire(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_acquire(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. file pointer is now positioned inside the new data. */
645 rc = read(fd1, buf, 1);
646 ASSERTF(rc == 1, "read 1 byte on foo1 failed: %s", strerror(errno));
647 ASSERTF(buf[0] == 'y', "invalid data found on foo2: %x", buf[0]);
649 rc = fstat(fd2, &stbuf);
650 ASSERTF(rc == 0, "stat failed on 'foo2': %s", strerror(errno));
651 ASSERTF(stbuf.st_size == foo1_size,
652 "invalid size found: %llu instead of %zu",
653 (unsigned long long)stbuf.st_size, foo1_size);
655 /* Read from fd2. After the swap, the file pointer is past the data. */
656 rc = read(fd2, buf, 1);
657 ASSERTF(rc == 0, "unexpected read returned rc=%d (errno %s)",
658 rc, strerror(errno));
661 ASSERTF(rc == 0, "close failed: %s", strerror(errno));
664 ASSERTF(rc == 0, "close failed: %s", strerror(errno));
667 /* Test multiple swaps between 2 files */
668 static void test30(void)
673 size_t foo1_size = 2000;
674 size_t foo2_size = 5000;
678 rc = mkdir(mainpath, 0);
679 ASSERTF(rc == 0, "mkdir failed for '%s': %s",
680 mainpath, strerror(errno));
682 fd1 = create_file("foo1", foo1_size, 'x');
683 fd2 = create_file("foo2", foo2_size, 'y');
685 for (i = 0; i < 1000; i++) {
686 rc = llapi_fswap_layouts(fd1, fd2, 0, 0, 0);
687 ASSERTF(rc == 0, "llapi_fswap_layouts failed: %s",
690 rc = fstat(fd1, &stbuf);
691 ASSERTF(rc == 0, "stat failed on 'foo1': %s", strerror(errno));
692 ASSERTF(stbuf.st_size == i % 2 ? foo2_size : foo1_size,
693 "invalid size found: %llu instead of %zu",
694 (unsigned long long)stbuf.st_size,
695 i % 2 ? foo2_size : foo1_size);
697 rc = fstat(fd2, &stbuf);
698 ASSERTF(rc == 0, "stat failed on 'foo2': %s", strerror(errno));
699 ASSERTF(stbuf.st_size == i % 2 ? foo1_size : foo2_size,
700 "invalid size found: %llu instead of %zu",
701 (unsigned long long)stbuf.st_size,
702 i % 2 ? foo1_size : foo2_size);
709 /* Test multiple swaps between 3 files */
710 static void test31(void)
716 size_t foo1_size = 2000;
717 size_t foo2_size = 5000;
718 size_t foo3_size = 8000;
723 rc = mkdir(mainpath, 0);
724 ASSERTF(rc == 0, "mkdir failed for '%s': %s",
725 mainpath, strerror(errno));
727 fd1 = create_file("foo1", foo1_size, 'x');
728 fd2 = create_file("foo2", foo2_size, 'y');
729 fd3 = create_file("foo3", foo3_size, 'z');
731 /* Note: swapping 3 fd this way will be back to original
732 * layouts every 2 loops.
734 for (i = 0; i < 999; i++) {
735 rc = llapi_fswap_layouts(fd1, fd2, 0, 0, 0);
736 ASSERTF(rc == 0, "llapi_fswap_layouts failed: %s",
739 rc = llapi_fswap_layouts(fd2, fd3, 0, 0, 0);
740 ASSERTF(rc == 0, "llapi_fswap_layouts failed: %s",
743 rc = llapi_fswap_layouts(fd1, fd3, 0, 0, 0);
744 ASSERTF(rc == 0, "llapi_fswap_layouts failed: %s",
748 rc = fstat(fd1, &stbuf);
749 ASSERTF(rc == 0, "stat failed on 'foo2': %s", strerror(errno));
750 ASSERTF(stbuf.st_size == foo1_size,
751 "invalid size found: %llu instead of %zu",
752 (unsigned long long)stbuf.st_size, foo1_size);
754 rc = fstat(fd2, &stbuf);
755 ASSERTF(rc == 0, "stat failed on 'foo2': %s", strerror(errno));
756 ASSERTF(stbuf.st_size == foo3_size,
757 "invalid size found: %llu instead of %zu",
758 (unsigned long long)stbuf.st_size, foo3_size);
760 rc = fstat(fd3, &stbuf);
761 ASSERTF(rc == 0, "stat failed on 'foo2': %s", strerror(errno));
762 ASSERTF(stbuf.st_size == foo2_size,
763 "invalid size found: %llu instead of %zu",
764 (unsigned long long)stbuf.st_size, foo2_size);
771 /* Swap with lease */
772 static void test40(void)
777 size_t foo1_size = 2000;
778 size_t foo2_size = 5000;
780 rc = mkdir(mainpath, 0);
781 ASSERTF(rc == 0, "mkdir failed for '%s': %s",
782 mainpath, strerror(errno));
784 fd1 = create_file("foo1", foo1_size, 'x');
785 fd2 = create_file("foo2", foo2_size, 'y');
787 rc = llapi_lease_acquire(fd1, LL_LEASE_RDLCK);
788 ASSERTF(rc == 0, "cannot get lease '%s': %s", mainpath, strerror(-rc));
790 rc = llapi_lease_check(fd1);
791 ASSERTF(rc == LL_LEASE_RDLCK,
792 "invalid lease type on '%s': %s", mainpath, strerror(-rc));
794 rc = llapi_fswap_layouts(fd1, fd2, 0, 0, SWAP_LAYOUTS_CLOSE);
795 ASSERTF(rc == 0, "llapi_fswap_layouts failed: %s",
798 rc = llapi_lease_check(fd1);
799 ASSERTF(rc == 0, "lease not lost on '%s': %s", mainpath, strerror(-rc));
801 rc = llapi_lease_release(fd1);
802 ASSERTF(rc == -ENOLCK,
803 "was able to put back lease: %s", strerror(-rc));
805 rc = llapi_lease_check(fd1);
806 ASSERTF(rc == 0, "lease not lost on '%s': %s", mainpath, strerror(-rc));
809 ASSERTF(rc == 0, "close failed: %s", strerror(errno));
812 ASSERTF(rc == 0, "close failed: %s", strerror(errno));
815 /* Swap with close but no lease */
816 static void test41(void)
821 size_t foo1_size = 2000;
822 size_t foo2_size = 5000;
824 rc = mkdir(mainpath, 0);
825 ASSERTF(rc == 0, "mkdir failed for '%s': %s",
826 mainpath, strerror(errno));
828 fd1 = create_file("foo1", foo1_size, 'x');
829 fd2 = create_file("foo2", foo2_size, 'y');
831 rc = llapi_fswap_layouts(fd1, fd2, 0, 0, SWAP_LAYOUTS_CLOSE);
832 ASSERTF(rc == -ENOLCK, "llapi_fswap_layouts failed: %s",
835 /* swap failed, so fd1 has to be closed. */
837 ASSERTF(rc == 0, "close failed: %s", strerror(errno));
840 ASSERTF(rc == 0, "close failed: %s", strerror(errno));
843 /* swap with data versions */
844 static void test42(void)
849 size_t foo1_size = 2000;
850 size_t foo2_size = 5000;
855 __u64 new_new_dv1 = 0;
856 __u64 new_new_dv2 = 0;
860 rc = mkdir(mainpath, 0);
861 ASSERTF(rc == 0, "mkdir failed for '%s': %s",
862 mainpath, strerror(errno));
864 /* Get dataversion for two files. Make sure values are different so that
865 * the following checks make sense.
867 fd1 = create_file("foo1", foo1_size, 'x');
869 rc = llapi_get_data_version(fd1, &dv1, LL_DV_RD_FLUSH);
870 ASSERTF(rc == 0, "cannot get dataversion for fd1: %s", strerror(-rc));
871 ASSERTF(dv1 != 0, "got dataversion 0 for fd1");
874 fd2 = create_file("foo2", foo2_size, 'y');
876 rc = llapi_get_data_version(fd2, &dv2, LL_DV_RD_FLUSH);
877 ASSERTF(rc == 0, "cannot get dataversion for fd2: %s",
879 ASSERTF(dv2 != 0, "got dataversion 0 for fd2");
887 /* swaps that should fail */
888 rc = llapi_fswap_layouts(fd1, fd2, 0, 0, SWAP_LAYOUTS_CHECK_DV1);
889 ASSERTF(rc == -EAGAIN, "incorrect return from swap: %s", strerror(-rc));
891 rc = llapi_fswap_layouts(fd1, fd2, dv1 + 456789, 0,
892 SWAP_LAYOUTS_CHECK_DV1);
893 ASSERTF(rc == -EAGAIN, "incorrect return from swap: %s", strerror(-rc));
895 rc = llapi_fswap_layouts(fd1, fd2, 0, 0, SWAP_LAYOUTS_CHECK_DV2);
896 ASSERTF(rc == -EAGAIN, "incorrect return from swap: %s", strerror(-rc));
898 rc = llapi_fswap_layouts(fd1, fd2, 0, dv2 + 987654,
899 SWAP_LAYOUTS_CHECK_DV2);
900 ASSERTF(rc == -EAGAIN, "incorrect return from swap: %s", strerror(-rc));
902 rc = llapi_fswap_layouts(fd1, fd2, 0, 0,
903 SWAP_LAYOUTS_CHECK_DV1 |
904 SWAP_LAYOUTS_CHECK_DV2);
905 ASSERTF(rc == -EAGAIN, "incorrect return from swap: %s", strerror(-rc));
907 rc = llapi_fswap_layouts(fd1, fd2, dv1 + 456789, 0,
908 SWAP_LAYOUTS_CHECK_DV1 |
909 SWAP_LAYOUTS_CHECK_DV2);
910 ASSERTF(rc == -EAGAIN, "incorrect return from swap: %s", strerror(-rc));
912 rc = llapi_fswap_layouts(fd1, fd2, dv1 + 456789, dv2 + 987654,
913 SWAP_LAYOUTS_CHECK_DV1 |
914 SWAP_LAYOUTS_CHECK_DV2);
915 ASSERTF(rc == -EAGAIN, "incorrect return from swap: %s", strerror(-rc));
917 rc = llapi_fswap_layouts(fd1, fd2, dv1, 0,
918 SWAP_LAYOUTS_CHECK_DV1 |
919 SWAP_LAYOUTS_CHECK_DV2);
920 ASSERTF(rc == -EAGAIN, "incorrect return from swap: %s", strerror(-rc));
922 rc = llapi_fswap_layouts(fd1, fd2, 0, dv2,
923 SWAP_LAYOUTS_CHECK_DV1 |
924 SWAP_LAYOUTS_CHECK_DV2);
925 ASSERTF(rc == -EAGAIN, "incorrect return from swap: %s", strerror(-rc));
927 rc = llapi_fswap_layouts(fd1, fd2, dv1, dv2 + 567,
928 SWAP_LAYOUTS_CHECK_DV1 |
929 SWAP_LAYOUTS_CHECK_DV2);
930 ASSERTF(rc == -EAGAIN, "incorrect return from swap: %s", strerror(-rc));
932 printf("DV = %llx and %llx\n", dv1, dv2);
934 /* Finally, a good swap */
935 rc = llapi_fswap_layouts(fd1, fd2, dv1, dv2,
936 SWAP_LAYOUTS_CHECK_DV1 |
937 SWAP_LAYOUTS_CHECK_DV2);
938 ASSERTF(rc == 0, "incorrect return from swap: %s", strerror(-rc));
940 /* Check dataversion. */
941 rc = llapi_get_data_version(fd1, &new_dv1, LL_DV_RD_FLUSH);
943 "cannot get new dataversion for fd1: %s", strerror(-rc));
944 ASSERTF(dv1 != 0, "got dataversion 0 for fd1");
945 ASSERTF(dv1 != new_dv1, "got identical dataversion for fd1: %llx", dv1);
947 rc = llapi_get_data_version(fd2, &new_dv2, LL_DV_RD_FLUSH);
949 "cannot get new dataversion for fd2: %s", strerror(-rc));
950 ASSERTF(dv2 != 0, "got dataversion 0 for fd2");
951 ASSERTF(dv2 != new_dv2, "got identical dataversion for fd2: %llx", dv1);
953 printf("new DV = %llx and %llx\n", new_dv1, new_dv2);
955 /* Try again with same parameters. */
956 rc = llapi_fswap_layouts(fd1, fd2, dv1, dv2,
957 SWAP_LAYOUTS_CHECK_DV1 |
958 SWAP_LAYOUTS_CHECK_DV2);
959 ASSERTF(rc == -EAGAIN, "incorrect return from swap: %s", strerror(-rc));
964 /* Reopen the files and check again the dataversion */
965 name_fd1 = create_file_name("foo1");
966 fd1 = open(name_fd1, O_RDONLY);
968 "open failed for '%s': %s", name_fd1, strerror(errno));
970 rc = llapi_get_data_version(fd1, &new_new_dv1, LL_DV_RD_FLUSH);
971 ASSERTF(rc == 0, "cannot get dataversion for fd1: %s", strerror(-rc));
972 ASSERTF(new_new_dv1 != 0, "got dataversion 0 for fd1");
973 ASSERTF(new_dv1 == new_new_dv1,
974 "dataversion changed after re-opening: %llx and %llx",
975 new_dv1, new_new_dv1);
977 name_fd2 = create_file_name("foo2");
978 fd2 = open(name_fd2, O_RDONLY);
980 "open failed for '%s': %s", name_fd2, strerror(errno));
982 rc = llapi_get_data_version(fd2, &new_new_dv2, LL_DV_RD_FLUSH);
983 ASSERTF(rc == 0, "cannot get dataversion for fd2: %s", strerror(-rc));
984 ASSERTF(new_new_dv2 != 0, "got dataversion 0 for fd2");
985 ASSERTF(new_dv2 == new_new_dv2,
986 "dataversion changed after re-opening: %llx and %llx",
987 new_dv2, new_new_dv2);
989 printf("DV= %llx and %llx\n", new_new_dv1, new_new_dv2);
998 /* swap group lock, no group */
999 static void test50(void)
1004 size_t foo1_size = 2000;
1005 size_t foo2_size = 5000;
1007 rc = mkdir(mainpath, 0);
1008 ASSERTF(rc == 0, "mkdir failed for '%s': %s",
1009 mainpath, strerror(errno));
1011 fd1 = create_file("foo1", foo1_size, 'x');
1012 fd2 = create_file("foo2", foo2_size, 'y');
1014 rc = llapi_fswap_layouts_grouplock(fd1, fd2, 0, 0, 0, 0);
1015 ASSERTF(rc == 0, "llapi_fswap_layouts_grouplock failed: %s",
1022 /* swap group lock, with group */
1023 static void test51(void)
1028 size_t foo1_size = 2000;
1029 size_t foo2_size = 5000;
1031 rc = mkdir(mainpath, 0);
1032 ASSERTF(rc == 0, "mkdir failed for '%s': %s",
1033 mainpath, strerror(errno));
1035 fd1 = create_file("foo1", foo1_size, 'x');
1036 fd2 = create_file("foo2", foo2_size, 'y');
1038 rc = llapi_fswap_layouts_grouplock(fd1, fd2, 0, 0, 456789, 0);
1039 ASSERTF(rc == 0, "llapi_fswap_layouts_grouplock failed: %s",
1046 /* swap group lock, with existing group locks */
1047 static void test52(void)
1052 size_t foo1_size = 2000;
1053 size_t foo2_size = 5000;
1056 rc = mkdir(mainpath, 0);
1057 ASSERTF(rc == 0, "mkdir failed for '%s': %s",
1058 mainpath, strerror(errno));
1060 fd1 = create_file("foo1", foo1_size, 'x');
1061 fd2 = create_file("foo2", foo2_size, 'y');
1063 /* lock a descriptor, but swap without */
1064 rc = llapi_group_lock(fd1, gid);
1065 ASSERTF(rc == 0, "cannot lock 'foo1': %s", strerror(-rc));
1067 rc = llapi_fswap_layouts_grouplock(fd1, fd2, 0, 0, 0, 0);
1068 ASSERTF(rc == 0, "llapi_fswap_layouts_grouplock failed: %s",
1071 rc = llapi_group_unlock(fd1, gid);
1072 ASSERTF(rc == 0, "cannot unlock 'foo1': %s", strerror(-rc));
1078 /* Swap group lock, with existing group locks, on second descriptor */
1079 static void test53(void)
1084 size_t foo1_size = 2000;
1085 size_t foo2_size = 5000;
1088 rc = mkdir(mainpath, 0);
1089 ASSERTF(rc == 0, "mkdir failed for '%s': %s",
1090 mainpath, strerror(errno));
1092 fd1 = create_file("foo1", foo1_size, 'x');
1093 fd2 = create_file("foo2", foo2_size, 'y');
1095 /* lock a descriptor, but swap without */
1096 rc = llapi_group_lock(fd2, gid);
1097 ASSERTF(rc == 0, "cannot lock 'foo1': %s", strerror(-rc));
1099 rc = llapi_fswap_layouts_grouplock(fd1, fd2, 0, 0, 0, 0);
1100 ASSERTF(rc == 0, "llapi_fswap_layouts_grouplock failed: %s",
1103 rc = llapi_group_unlock(fd2, gid);
1104 ASSERTF(rc == 0, "cannot unlock 'foo1': %s", strerror(-rc));
1110 /* swap group lock, lock a descriptor, and try to swap with it. */
1111 static void test54(void)
1116 size_t foo1_size = 2000;
1117 size_t foo2_size = 5000;
1120 rc = mkdir(mainpath, 0);
1121 ASSERTF(rc == 0, "mkdir failed for '%s': %s",
1122 mainpath, strerror(errno));
1124 fd1 = create_file("foo1", foo1_size, 'x');
1125 fd2 = create_file("foo2", foo2_size, 'y');
1128 rc = llapi_group_lock(fd1, gid);
1129 ASSERTF(rc == 0, "cannot lock 'foo1': %s", strerror(-rc));
1131 rc = llapi_fswap_layouts_grouplock(fd1, fd2, 0, 0, gid, 0);
1132 ASSERTF(rc == -EINVAL, "llapi_fswap_layouts_grouplock failed: %s",
1135 rc = llapi_group_unlock(fd1, gid);
1136 ASSERTF(rc == 0, "cannot unlock 'foo1': %s", strerror(-rc));
1142 /* Swap group lock, lock a descriptor, and try to swap with it, on
1143 * 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 one. */
1176 static void test56(void)
1181 size_t foo1_size = 2000;
1182 size_t foo2_size = 5000;
1186 rc = mkdir(mainpath, 0);
1187 ASSERTF(rc == 0, "mkdir failed for '%s': %s",
1188 mainpath, strerror(errno));
1190 fd1 = create_file("foo1", foo1_size, 'x');
1191 fd2 = create_file("foo2", foo2_size, 'y');
1193 rc = llapi_group_lock(fd1, gid1);
1194 ASSERTF(rc == 0, "cannot lock 'foo1': %s", strerror(-rc));
1196 rc = llapi_group_lock(fd2, gid2);
1197 ASSERTF(rc == 0, "cannot lock 'foo1': %s", strerror(-rc));
1199 rc = llapi_fswap_layouts_grouplock(fd1, fd2, 0, 0, 0, 0);
1200 ASSERTF(rc == 0, "llapi_fswap_layouts_grouplock failed: %s",
1203 rc = llapi_group_unlock(fd1, gid1);
1204 ASSERTF(rc == 0, "cannot unlock 'foo1': %s", strerror(-rc));
1206 rc = llapi_group_unlock(fd2, gid2);
1207 ASSERTF(rc == 0, "cannot unlock 'foo2': %s", strerror(-rc));
1213 /* Swap group lock, lock both descriptor, and try to swap with another one. */
1214 static void test57(void)
1219 size_t foo1_size = 2000;
1220 size_t foo2_size = 5000;
1224 rc = mkdir(mainpath, 0);
1225 ASSERTF(rc == 0, "mkdir failed for '%s': %s",
1226 mainpath, strerror(errno));
1228 fd1 = create_file("foo1", foo1_size, 'x');
1229 fd2 = create_file("foo2", foo2_size, 'y');
1231 rc = llapi_group_lock(fd1, gid1);
1232 ASSERTF(rc == 0, "cannot lock 'foo1': %s", strerror(-rc));
1234 rc = llapi_group_lock(fd2, gid2);
1235 ASSERTF(rc == 0, "cannot lock 'foo1': %s", strerror(-rc));
1237 rc = llapi_fswap_layouts_grouplock(fd1, fd2, 0, 0, gid1+gid2, 0);
1238 ASSERTF(rc == -EINVAL, "llapi_fswap_layouts_grouplock failed: %s",
1241 rc = llapi_group_unlock(fd1, gid1);
1242 ASSERTF(rc == 0, "cannot unlock 'foo1': %s", strerror(-rc));
1244 rc = llapi_group_unlock(fd2, gid2);
1245 ASSERTF(rc == 0, "cannot unlock 'foo2': %s", strerror(-rc));
1251 /* Swap group lock, lock both descriptor with same gid, and try to
1254 static void test58(void)
1259 size_t foo1_size = 2000;
1260 size_t foo2_size = 5000;
1263 rc = mkdir(mainpath, 0);
1264 ASSERTF(rc == 0, "mkdir failed for '%s': %s",
1265 mainpath, strerror(errno));
1267 fd1 = create_file("foo1", foo1_size, 'x');
1268 fd2 = create_file("foo2", foo2_size, 'y');
1270 rc = llapi_group_lock(fd1, gid);
1271 ASSERTF(rc == 0, "cannot lock 'foo1': %s", strerror(-rc));
1273 rc = llapi_group_lock(fd2, gid);
1274 ASSERTF(rc == 0, "cannot lock 'foo1': %s", strerror(-rc));
1276 rc = llapi_fswap_layouts_grouplock(fd1, fd2, 0, 0, gid, 0);
1277 ASSERTF(rc == -EINVAL, "llapi_fswap_layouts_grouplock failed: %s",
1280 rc = llapi_group_unlock(fd1, gid);
1281 ASSERTF(rc == 0, "cannot unlock 'foo1': %s", strerror(-rc));
1283 rc = llapi_group_unlock(fd2, gid);
1284 ASSERTF(rc == 0, "cannot unlock 'foo2': %s", strerror(-rc));
1290 /* Swap group lock, lock both descriptor with same gid, and swap with none. */
1291 static void test59(void)
1296 size_t foo1_size = 2000;
1297 size_t foo2_size = 5000;
1300 rc = mkdir(mainpath, 0);
1301 ASSERTF(rc == 0, "mkdir failed for '%s': %s",
1302 mainpath, strerror(errno));
1304 fd1 = create_file("foo1", foo1_size, 'x');
1305 fd2 = create_file("foo2", foo2_size, 'y');
1307 rc = llapi_group_lock(fd1, gid);
1308 ASSERTF(rc == 0, "cannot lock 'foo1': %s", strerror(-rc));
1310 rc = llapi_group_lock(fd2, gid);
1311 ASSERTF(rc == 0, "cannot lock 'foo1': %s", strerror(-rc));
1313 rc = llapi_fswap_layouts_grouplock(fd1, fd2, 0, 0, 0, 0);
1314 ASSERTF(rc == 0, "llapi_fswap_layouts_grouplock failed: %s",
1317 rc = llapi_group_unlock(fd1, gid);
1318 ASSERTF(rc == 0, "cannot unlock 'foo1': %s", strerror(-rc));
1320 rc = llapi_group_unlock(fd2, gid);
1321 ASSERTF(rc == 0, "cannot unlock 'foo2': %s", strerror(-rc));
1327 static void usage(char *prog)
1329 fprintf(stderr, "Usage: %s [-d lustre_dir]\n", prog);
1333 static void process_args(int argc, char *argv[])
1337 while ((c = getopt(argc, argv, "d:")) != -1) {
1340 lustre_dir = optarg;
1344 fprintf(stderr, "Unknown option '%c'\n", optopt);
1351 int main(int argc, char *argv[])
1356 process_args(argc, argv);
1357 if (lustre_dir == NULL)
1358 lustre_dir = "/mnt/lustre";
1360 rc = llapi_search_mounts(lustre_dir, 0, fsmountdir, fsname);
1362 fprintf(stderr, "Error: '%s': not a Lustre filesystem\n",
1364 return EXIT_FAILURE;
1367 /* Play nice with Lustre test scripts. Non-line buffered output
1368 * stream under I/O redirection may appear incorrectly.
1370 setvbuf(stdout, NULL, _IOLBF, 0);
1372 /* Create a test filename and reuse it. Remove possibly old files. */
1373 rc = snprintf(mainpath, sizeof(mainpath), "%s/%s", lustre_dir, maindir);
1374 ASSERTF(rc > 0 && rc < sizeof(mainpath), "invalid name for mainpath");
1403 return EXIT_SUCCESS;