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>
46 #include <lustre/lustre_idl.h>
48 #define ERROR(fmt, ...) \
49 fprintf(stderr, "%s: %s:%d: %s: " fmt "\n", \
50 program_invocation_short_name, __FILE__, __LINE__, \
51 __func__, ## __VA_ARGS__);
53 #define DIE(fmt, ...) \
55 ERROR(fmt, ## __VA_ARGS__); \
59 #define ASSERTF(cond, fmt, ...) \
62 DIE("assertion '%s' failed: "fmt, \
63 #cond, ## __VA_ARGS__); \
66 #define PERFORM(testfn) \
68 fprintf(stderr, "Starting test " #testfn " at %lld\n", \
69 (unsigned long long)time(NULL)); \
73 fprintf(stderr, "Finishing test " #testfn " at %lld\n", \
74 (unsigned long long)time(NULL)); \
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";
81 static char fsmountdir[PATH_MAX]; /* Lustre mountpoint */
82 static char *lustre_dir; /* Test directory inside Lustre */
84 /* Cleanup our test directory. */
85 static void cleanup(void)
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);
94 ASSERTF(rc != -1, "Cannot execute rm command");
95 ASSERTF(WEXITSTATUS(rc) == 0,
96 "rm command returned %d", WEXITSTATUS(rc));
99 /* Create a filename inside the test directory. Will assert on
101 static char *create_file_name(const char *name)
106 rc = asprintf(&filename, "%s/%s/%s", lustre_dir, maindir, name);
107 ASSERTF(rc > 0, "can't make filename for '%s'", name);
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)
121 filename = create_file_name(name);
123 fd = open(filename, O_CREAT|O_TRUNC|O_RDWR, 0600);
124 ASSERTF(fd >= 0, "open failed for '%s': %s",
125 filename, strerror(errno));
129 /* Fill-up the new file. */
130 memset(buf, c, sizeof(buf));
133 size_t to_write = size;
135 if (to_write > sizeof(buf))
136 to_write = sizeof(buf);
138 rc = write(fd, buf, to_write);
139 ASSERTF(rc > 0, "writing %zu bytes to '%s' failed: %s",
140 to_write, name, strerror(errno));
148 /* Test basic swap */
149 static void test10(void)
154 size_t foo1_size = 2000;
155 size_t foo2_size = 5000;
158 rc = mkdir(mainpath, 0);
159 ASSERTF(rc == 0, "mkdir failed for '%s': %s",
160 mainpath, strerror(errno));
162 fd1 = create_file("foo1", foo1_size, 'x');
163 fd2 = create_file("foo2", foo2_size, 'y');
165 rc = llapi_fswap_layouts(fd1, fd2, 0, 0, 0);
166 ASSERTF(rc == 0, "llapi_fswap_layouts failed: %s",
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);
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);
185 /* Test self swap. It's a no-op and will always succeed. */
186 static void test11(void)
190 size_t foo1_size = 2000;
192 rc = mkdir(mainpath, 0);
193 ASSERTF(rc == 0, "mkdir failed for '%s': %s",
194 mainpath, strerror(errno));
196 fd1 = create_file("foo1", foo1_size, 'x');
198 rc = llapi_fswap_layouts(fd1, fd1, 0, 0, 0);
199 ASSERTF(rc == 0, "llapi_fswap_layouts failed: %s",
205 /* Test self swap, on different handles. It's a no-op and will always
207 static void test12(void)
212 size_t foo1_size = 2000;
214 rc = mkdir(mainpath, 0);
215 ASSERTF(rc == 0, "mkdir failed for '%s': %s",
216 mainpath, strerror(errno));
218 fd1 = create_file("foo1", foo1_size, 'x');
220 ASSERTF(fd2 != -1, "dup failed: %s", strerror(errno));
222 rc = llapi_fswap_layouts(fd1, fd2, 0, 0, 0);
223 ASSERTF(rc == 0, "llapi_fswap_layouts failed: %s",
230 /* Swap with a non Lustre file */
231 static void test13(void)
236 size_t foo1_size = 2000;
238 rc = mkdir(mainpath, 0);
239 ASSERTF(rc == 0, "mkdir failed for '%s': %s",
240 mainpath, strerror(errno));
242 fd1 = create_file("foo1", foo1_size, 'x');
244 fd2 = open("/dev/null", O_RDWR);
245 ASSERTF(fd2 != -1, "open '/dev/null/' failed: %s", strerror(errno));
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",
256 rc = llapi_fswap_layouts(fd2, fd1, 0, 0, 0);
257 ASSERTF(rc == -ENOTTY, "llapi_fswap_layouts failed: %s",
264 /* Swap with bogus values */
265 static void test14(void)
269 rc = llapi_fswap_layouts(-6, -2, 0, 0, 0);
270 ASSERTF(rc == -EBADF, "llapi_fswap_layouts failed: %s",
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",
281 rc = llapi_fswap_layouts(456789076, 234567895, 0, 0, 0);
282 ASSERTF(rc == -EBADF, "llapi_fswap_layouts failed: %s",
286 /* Lease only test. */
287 static void test15(void)
294 rc = mkdir(mainpath, 0);
295 ASSERTF(rc == 0, "mkdir failed for '%s': %s",
296 mainpath, strerror(errno));
298 filename = create_file_name("foo1");
300 fd = create_file("foo1", 1000, 'x');
302 rc = llapi_lease_get(fd, LL_LEASE_RDLCK);
303 ASSERTF(rc == 0, "cannot get lease '%s': %s", filename, strerror(-rc));
307 /* Read lease on read file */
308 fd = open(filename, O_RDONLY);
309 ASSERTF(fd >= 0, "open failed for '%s': %s", filename, strerror(errno));
311 rc = llapi_lease_get(fd, LL_LEASE_RDLCK);
312 ASSERTF(rc == 0, "cannot get lease '%s': %s", filename, strerror(-rc));
314 rc = llapi_lease_check(fd);
315 ASSERTF(rc == LL_LEASE_RDLCK,
316 "invalid lease type on '%s': %s", filename, strerror(-rc));
320 /* Write lease on write file */
321 fd = open(filename, O_WRONLY);
322 ASSERTF(fd >= 0, "open failed for '%s': %s", filename, strerror(errno));
324 rc = llapi_lease_get(fd, LL_LEASE_WRLCK);
325 ASSERTF(rc == 0, "cannot get lease '%s': %s", filename, strerror(-rc));
327 rc = llapi_lease_check(fd);
328 ASSERTF(rc == LL_LEASE_WRLCK,
329 "invalid lease type on '%s': %s", filename, strerror(-rc));
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));
337 rc = llapi_lease_get(fd, LL_LEASE_RDLCK);
338 ASSERTF(rc == 0, "cannot get lease '%s': %s", filename, strerror(-rc));
340 rc = llapi_lease_check(fd);
341 ASSERTF(rc == LL_LEASE_RDLCK,
342 "invalid lease type on '%s': %s", filename, strerror(-rc));
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));
350 rc = llapi_lease_get(fd, LL_LEASE_WRLCK);
351 ASSERTF(rc == 0, "cannot get lease '%s': %s", filename, strerror(-rc));
353 rc = llapi_lease_check(fd);
354 ASSERTF(rc == LL_LEASE_WRLCK,
355 "invalid lease type on '%s': %s", filename, strerror(-rc));
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));
363 rc = llapi_lease_get(fd, LL_LEASE_RDLCK);
364 ASSERTF(rc == -EPERM, "cannot get lease '%s': %s",
365 filename, strerror(-rc));
367 rc = llapi_lease_check(fd);
369 "invalid lease type on '%s': %s", filename, strerror(-rc));
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));
377 rc = llapi_lease_get(fd, LL_LEASE_WRLCK);
378 ASSERTF(rc == -EPERM, "cannot get lease '%s': %s",
379 filename, strerror(-rc));
381 rc = llapi_lease_check(fd);
383 "invalid lease type on '%s': %s", filename, strerror(-rc));
387 /* Get read lease again */
388 fd = open(filename, O_RDWR);
389 ASSERTF(fd >= 0, "open failed for '%s': %s", filename, strerror(errno));
391 rc = llapi_lease_get(fd, LL_LEASE_RDLCK);
392 ASSERTF(rc == 0, "cannot get lease '%s': %s", filename, strerror(-rc));
394 rc = llapi_lease_get(fd, LL_LEASE_RDLCK);
395 ASSERTF(rc == -EBUSY, "can get lease '%s': %s",
396 filename, strerror(-rc));
398 rc = llapi_lease_check(fd);
399 ASSERTF(rc == LL_LEASE_RDLCK,
400 "invalid lease type on '%s': %s", filename, strerror(-rc));
404 /* Get write lease again */
405 fd = open(filename, O_RDWR);
406 ASSERTF(fd >= 0, "open failed for '%s': %s", filename, strerror(errno));
408 rc = llapi_lease_get(fd, LL_LEASE_WRLCK);
409 ASSERTF(rc == 0, "cannot get lease '%s': %s", filename, strerror(-rc));
411 rc = llapi_lease_get(fd, LL_LEASE_WRLCK);
412 ASSERTF(rc == -EBUSY, "can get lease '%s': %s",
413 filename, strerror(-rc));
415 rc = llapi_lease_check(fd);
416 ASSERTF(rc == LL_LEASE_WRLCK,
417 "invalid lease type on '%s': %s", filename, strerror(-rc));
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));
425 rc = llapi_lease_get(fd, LL_LEASE_RDLCK);
426 ASSERTF(rc == 0, "cannot get lease '%s': %s", filename, strerror(-rc));
428 rc = llapi_lease_check(fd);
429 ASSERTF(rc == LL_LEASE_RDLCK,
430 "invalid lease type on '%s': %s", filename, strerror(-rc));
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));
436 rc = llapi_lease_check(fd);
438 "invalid lease type on '%s': %s", filename, strerror(-rc));
440 rc = llapi_lease_get(fd, LL_LEASE_RDLCK);
441 ASSERTF(rc == 0, "cannot get lease '%s': %s", filename, strerror(-rc));
445 /* Get a write lease, release and get again */
446 fd = open(filename, O_RDWR);
447 ASSERTF(fd >= 0, "open failed for '%s': %s", filename, strerror(errno));
449 rc = llapi_lease_get(fd, LL_LEASE_WRLCK);
450 ASSERTF(rc == 0, "cannot get lease '%s': %s", filename, strerror(-rc));
452 rc = llapi_lease_check(fd);
453 ASSERTF(rc == LL_LEASE_WRLCK,
454 "invalid lease type on '%s': %s", filename, strerror(-rc));
456 rc = llapi_lease_put(fd);
457 ASSERTF(rc == LL_LEASE_WRLCK, "was not able to put back lease '%s': %s",
458 filename, strerror(-rc));
460 rc = llapi_lease_check(fd);
462 "invalid lease type on '%s': %s", filename, strerror(-rc));
464 rc = llapi_lease_get(fd, LL_LEASE_WRLCK);
465 ASSERTF(rc == 0, "cannot get lease '%s': %s", filename, strerror(-rc));
469 /* Get and put lease in a loop */
470 fd = open(filename, O_RDWR);
471 ASSERTF(fd >= 0, "open failed for '%s': %s", filename, strerror(errno));
473 for (i = 0; i < 1000; i++) {
474 rc = llapi_lease_get(fd, LL_LEASE_WRLCK);
475 ASSERTF(rc == 0, "cannot get lease '%s': %s",
476 filename, strerror(-rc));
478 rc = llapi_lease_put(fd);
479 ASSERTF(rc == LL_LEASE_WRLCK,
480 "was not able to put back lease '%s': %s",
481 filename, strerror(-rc));
483 rc = llapi_lease_get(fd, LL_LEASE_RDLCK);
484 ASSERTF(rc == 0, "cannot get lease '%s': %s",
485 filename, strerror(-rc));
487 rc = llapi_lease_put(fd);
488 ASSERTF(rc == LL_LEASE_RDLCK,
489 "was not able to put back lease '%s': %s",
490 filename, strerror(-rc));
495 /* Get a write lease, release and take a read one */
496 fd = open(filename, O_RDWR);
497 ASSERTF(fd >= 0, "open failed for '%s': %s", filename, strerror(errno));
499 rc = llapi_lease_get(fd, LL_LEASE_WRLCK);
500 ASSERTF(rc == 0, "cannot get lease '%s': %s", filename, strerror(-rc));
502 rc = llapi_lease_check(fd);
503 ASSERTF(rc == LL_LEASE_WRLCK,
504 "invalid lease type on '%s': %s", filename, strerror(-rc));
506 rc = llapi_lease_put(fd);
507 ASSERTF(rc == LL_LEASE_WRLCK, "was not able to put back lease '%s': %s",
508 filename, strerror(-rc));
510 rc = llapi_lease_check(fd);
512 "invalid lease type on '%s': %s", filename, strerror(-rc));
514 rc = llapi_lease_get(fd, LL_LEASE_RDLCK);
515 ASSERTF(rc == 0, "cannot get lease '%s': %s", filename, strerror(-rc));
519 /* Get a read lease, release and take a write one */
520 fd = open(filename, O_RDWR);
521 ASSERTF(fd >= 0, "open failed for '%s': %s", filename, strerror(errno));
523 rc = llapi_lease_get(fd, LL_LEASE_RDLCK);
524 ASSERTF(rc == 0, "cannot get lease '%s': %s", filename, strerror(-rc));
526 rc = llapi_lease_check(fd);
527 ASSERTF(rc == LL_LEASE_RDLCK,
528 "invalid lease type on '%s': %s", filename, strerror(-rc));
530 rc = llapi_lease_put(fd);
531 ASSERTF(rc == LL_LEASE_RDLCK, "was not able to put back lease '%s': %s",
532 filename, strerror(-rc));
534 rc = llapi_lease_check(fd);
536 "invalid lease type on '%s': %s", filename, strerror(-rc));
538 rc = llapi_lease_get(fd, LL_LEASE_WRLCK);
539 ASSERTF(rc == 0, "cannot get lease '%s': %s", filename, strerror(-rc));
546 /* Lease on file opened by FID */
547 static void test16(void)
554 rc = mkdir(mainpath, 0);
555 ASSERTF(rc == 0, "mkdir failed for '%s': %s",
556 mainpath, strerror(errno));
558 filename = create_file_name("foo1");
560 fd = create_file("foo1", 1000, 'x');
562 rc = llapi_path2fid(filename, &fid);
563 ASSERTF(rc == 0, "llapi_path2fid failed for '%s': %s",
564 filename, strerror(-rc));
568 fd = llapi_open_by_fid(fsmountdir, &fid,
569 O_RDWR | O_NOATIME | O_NONBLOCK | O_NOFOLLOW);
570 ASSERTF(fd >= 0, "open failed for '%s': %s", filename, strerror(errno));
572 rc = llapi_lease_get(fd, LL_LEASE_RDLCK);
573 ASSERTF(rc == 0, "cannot get lease '%s': %s", filename, strerror(-rc));
580 /* Lease on directories */
581 static void test17(void)
587 rc = mkdir(mainpath, 0);
588 ASSERTF(rc == 0, "mkdir failed for '%s': %s",
589 mainpath, strerror(errno));
591 fd = open(mainpath, O_DIRECTORY);
592 ASSERTF(fd >= 0, "open failed for '%s': %s", mainpath, strerror(errno));
594 rc = llapi_lease_get(fd, LL_LEASE_RDLCK);
595 ASSERTF(rc == -ENOTTY, "can get lease on directory '%s': %s",
596 mainpath, strerror(-rc));
600 /* On lustre mountpoint */
601 fd = open(fsmountdir, O_DIRECTORY);
602 ASSERTF(fd >= 0, "open failed for '%s': %s", mainpath, strerror(errno));
604 rc = llapi_lease_get(fd, LL_LEASE_RDLCK);
605 ASSERTF(rc == -ENOTTY, "can get lease on directory '%s': %s",
606 mainpath, strerror(-rc));
612 static void test20(void)
617 size_t foo1_size = 2000;
618 size_t foo2_size = 5000;
623 rc = mkdir(mainpath, 0);
624 ASSERTF(rc == 0, "mkdir failed for '%s': %s",
625 mainpath, strerror(errno));
627 fd1 = create_file("foo1", foo1_size, 'x');
628 fd2 = create_file("foo2", foo2_size, 'y');
630 /* foo2 is bigger than foo1. Read a byte in foo2, past foo1_size. */
631 offset = lseek(fd2, foo1_size + 100, SEEK_SET);
632 ASSERTF(offset == foo1_size + 100, "lseek to pos %zu failed: %s",
633 foo1_size + 100, strerror(errno));
635 rc = read(fd2, buf, 1);
636 ASSERTF(rc == 1, "read 1 byte on foo2 failed: %s, rc=%d",
637 strerror(errno), rc);
638 ASSERTF(buf[0] == 'y', "invalid data found on foo2: %x", buf[0]);
641 rc = llapi_fswap_layouts(fd1, fd2, 0, 0, 0);
642 ASSERTF(rc == 0, "llapi_fswap_layouts failed: %s",
645 /* Read from fd1. Its file pointer is now positioned inside
647 rc = read(fd1, buf, 1);
648 ASSERTF(rc == 1, "read 1 byte on foo1 failed: %s", strerror(errno));
649 ASSERTF(buf[0] == 'y', "invalid data found on foo2: %x", buf[0]);
651 rc = fstat(fd2, &stbuf);
652 ASSERTF(rc == 0, "stat failed on 'foo2': %s", strerror(errno));
653 ASSERTF(stbuf.st_size == foo1_size,
654 "invalid size found: %llu instead of %zu",
655 (unsigned long long)stbuf.st_size, foo1_size);
657 /* Read from fd2. After the swap, the file pointer is past the
659 rc = read(fd2, buf, 1);
660 ASSERTF(rc == 0, "unexpected read returned rc=%d (errno %s)",
661 rc, strerror(errno));
664 ASSERTF(rc == 0, "close failed: %s", strerror(errno));
667 ASSERTF(rc == 0, "close failed: %s", strerror(errno));
670 /* Test multiple swaps between 2 files */
671 static void test30(void)
676 size_t foo1_size = 2000;
677 size_t foo2_size = 5000;
681 rc = mkdir(mainpath, 0);
682 ASSERTF(rc == 0, "mkdir failed for '%s': %s",
683 mainpath, strerror(errno));
685 fd1 = create_file("foo1", foo1_size, 'x');
686 fd2 = create_file("foo2", foo2_size, 'y');
688 for (i = 0; i < 1000; i++) {
689 rc = llapi_fswap_layouts(fd1, fd2, 0, 0, 0);
690 ASSERTF(rc == 0, "llapi_fswap_layouts failed: %s",
693 rc = fstat(fd1, &stbuf);
694 ASSERTF(rc == 0, "stat failed on 'foo1': %s", strerror(errno));
695 ASSERTF(stbuf.st_size == i % 2 ? foo2_size : foo1_size,
696 "invalid size found: %llu instead of %zu",
697 (unsigned long long)stbuf.st_size,
698 i % 2 ? foo2_size : foo1_size);
700 rc = fstat(fd2, &stbuf);
701 ASSERTF(rc == 0, "stat failed on 'foo2': %s", strerror(errno));
702 ASSERTF(stbuf.st_size == i % 2 ? foo1_size : foo2_size,
703 "invalid size found: %llu instead of %zu",
704 (unsigned long long)stbuf.st_size,
705 i % 2 ? foo1_size : foo2_size);
712 /* Test multiple swaps between 3 files */
713 static void test31(void)
719 size_t foo1_size = 2000;
720 size_t foo2_size = 5000;
721 size_t foo3_size = 8000;
726 rc = mkdir(mainpath, 0);
727 ASSERTF(rc == 0, "mkdir failed for '%s': %s",
728 mainpath, strerror(errno));
730 fd1 = create_file("foo1", foo1_size, 'x');
731 fd2 = create_file("foo2", foo2_size, 'y');
732 fd3 = create_file("foo3", foo3_size, 'z');
734 /* Note: swapping 3 fd this way will be back to original
735 * layouts every 2 loops. */
736 for (i = 0; i < 999; i++) {
737 rc = llapi_fswap_layouts(fd1, fd2, 0, 0, 0);
738 ASSERTF(rc == 0, "llapi_fswap_layouts failed: %s",
741 rc = llapi_fswap_layouts(fd2, fd3, 0, 0, 0);
742 ASSERTF(rc == 0, "llapi_fswap_layouts failed: %s",
745 rc = llapi_fswap_layouts(fd1, fd3, 0, 0, 0);
746 ASSERTF(rc == 0, "llapi_fswap_layouts failed: %s",
750 rc = fstat(fd1, &stbuf);
751 ASSERTF(rc == 0, "stat failed on 'foo2': %s", strerror(errno));
752 ASSERTF(stbuf.st_size == foo1_size,
753 "invalid size found: %llu instead of %zu",
754 (unsigned long long)stbuf.st_size, foo1_size);
756 rc = fstat(fd2, &stbuf);
757 ASSERTF(rc == 0, "stat failed on 'foo2': %s", strerror(errno));
758 ASSERTF(stbuf.st_size == foo3_size,
759 "invalid size found: %llu instead of %zu",
760 (unsigned long long)stbuf.st_size, foo3_size);
762 rc = fstat(fd3, &stbuf);
763 ASSERTF(rc == 0, "stat failed on 'foo2': %s", strerror(errno));
764 ASSERTF(stbuf.st_size == foo2_size,
765 "invalid size found: %llu instead of %zu",
766 (unsigned long long)stbuf.st_size, foo2_size);
773 /* Swap with lease */
774 static void test40(void)
779 size_t foo1_size = 2000;
780 size_t foo2_size = 5000;
782 rc = mkdir(mainpath, 0);
783 ASSERTF(rc == 0, "mkdir failed for '%s': %s",
784 mainpath, strerror(errno));
786 fd1 = create_file("foo1", foo1_size, 'x');
787 fd2 = create_file("foo2", foo2_size, 'y');
789 rc = llapi_lease_get(fd1, LL_LEASE_RDLCK);
790 ASSERTF(rc == 0, "cannot get lease '%s': %s", mainpath, strerror(-rc));
792 rc = llapi_lease_check(fd1);
793 ASSERTF(rc == LL_LEASE_RDLCK,
794 "invalid lease type on '%s': %s", mainpath, strerror(-rc));
796 rc = llapi_fswap_layouts(fd1, fd2, 0, 0, SWAP_LAYOUTS_CLOSE);
797 ASSERTF(rc == 0, "llapi_fswap_layouts failed: %s",
800 rc = llapi_lease_check(fd1);
801 ASSERTF(rc == 0, "lease not lost on '%s': %s", mainpath, strerror(-rc));
803 rc = llapi_lease_put(fd1);
804 ASSERTF(rc == -ENOLCK,
805 "was able to put back lease: %s", strerror(-rc));
807 rc = llapi_lease_check(fd1);
808 ASSERTF(rc == 0, "lease not lost on '%s': %s", mainpath, strerror(-rc));
811 ASSERTF(rc == 0, "close failed: %s", strerror(errno));
814 ASSERTF(rc == 0, "close failed: %s", strerror(errno));
817 /* Swap with close but no lease */
818 static void test41(void)
823 size_t foo1_size = 2000;
824 size_t foo2_size = 5000;
826 rc = mkdir(mainpath, 0);
827 ASSERTF(rc == 0, "mkdir failed for '%s': %s",
828 mainpath, strerror(errno));
830 fd1 = create_file("foo1", foo1_size, 'x');
831 fd2 = create_file("foo2", foo2_size, 'y');
833 rc = llapi_fswap_layouts(fd1, fd2, 0, 0, SWAP_LAYOUTS_CLOSE);
834 ASSERTF(rc == -ENOLCK, "llapi_fswap_layouts failed: %s",
837 /* swap failed, so fd1 has to be closed. */
839 ASSERTF(rc == 0, "close failed: %s", strerror(errno));
842 ASSERTF(rc == 0, "close failed: %s", strerror(errno));
845 /* swap with data versions */
846 static void test42(void)
851 size_t foo1_size = 2000;
852 size_t foo2_size = 5000;
857 __u64 new_new_dv1 = 0;
858 __u64 new_new_dv2 = 0;
862 rc = mkdir(mainpath, 0);
863 ASSERTF(rc == 0, "mkdir failed for '%s': %s",
864 mainpath, strerror(errno));
866 /* Get dataversion for two files.
867 * Make sure values are different so that the following checks make
869 fd1 = create_file("foo1", foo1_size, 'x');
871 rc = llapi_get_data_version(fd1, &dv1, LL_DV_RD_FLUSH);
872 ASSERTF(rc == 0, "cannot get dataversion for fd1: %s", strerror(-rc));
873 ASSERTF(dv1 != 0, "got dataversion 0 for fd1");
876 fd2 = create_file("foo2", foo2_size, 'y');
878 rc = llapi_get_data_version(fd2, &dv2, LL_DV_RD_FLUSH);
879 ASSERTF(rc == 0, "cannot get dataversion for fd2: %s",
881 ASSERTF(dv2 != 0, "got dataversion 0 for fd2");
889 /* swaps that should fail */
890 rc = llapi_fswap_layouts(fd1, fd2, 0, 0, SWAP_LAYOUTS_CHECK_DV1);
891 ASSERTF(rc == -EAGAIN, "incorrect return from swap: %s", strerror(-rc));
893 rc = llapi_fswap_layouts(fd1, fd2, dv1 + 456789, 0,
894 SWAP_LAYOUTS_CHECK_DV1);
895 ASSERTF(rc == -EAGAIN, "incorrect return from swap: %s", strerror(-rc));
897 rc = llapi_fswap_layouts(fd1, fd2, 0, 0, SWAP_LAYOUTS_CHECK_DV2);
898 ASSERTF(rc == -EAGAIN, "incorrect return from swap: %s", strerror(-rc));
900 rc = llapi_fswap_layouts(fd1, fd2, 0, dv2 + 987654,
901 SWAP_LAYOUTS_CHECK_DV2);
902 ASSERTF(rc == -EAGAIN, "incorrect return from swap: %s", strerror(-rc));
904 rc = llapi_fswap_layouts(fd1, fd2, 0, 0,
905 SWAP_LAYOUTS_CHECK_DV1 |
906 SWAP_LAYOUTS_CHECK_DV2);
907 ASSERTF(rc == -EAGAIN, "incorrect return from swap: %s", strerror(-rc));
909 rc = llapi_fswap_layouts(fd1, fd2, dv1 + 456789, 0,
910 SWAP_LAYOUTS_CHECK_DV1 |
911 SWAP_LAYOUTS_CHECK_DV2);
912 ASSERTF(rc == -EAGAIN, "incorrect return from swap: %s", strerror(-rc));
914 rc = llapi_fswap_layouts(fd1, fd2, dv1 + 456789, dv2 + 987654,
915 SWAP_LAYOUTS_CHECK_DV1 |
916 SWAP_LAYOUTS_CHECK_DV2);
917 ASSERTF(rc == -EAGAIN, "incorrect return from swap: %s", strerror(-rc));
919 rc = llapi_fswap_layouts(fd1, fd2, dv1, 0,
920 SWAP_LAYOUTS_CHECK_DV1 |
921 SWAP_LAYOUTS_CHECK_DV2);
922 ASSERTF(rc == -EAGAIN, "incorrect return from swap: %s", strerror(-rc));
924 rc = llapi_fswap_layouts(fd1, fd2, 0, dv2,
925 SWAP_LAYOUTS_CHECK_DV1 |
926 SWAP_LAYOUTS_CHECK_DV2);
927 ASSERTF(rc == -EAGAIN, "incorrect return from swap: %s", strerror(-rc));
929 rc = llapi_fswap_layouts(fd1, fd2, dv1, dv2 + 567,
930 SWAP_LAYOUTS_CHECK_DV1 |
931 SWAP_LAYOUTS_CHECK_DV2);
932 ASSERTF(rc == -EAGAIN, "incorrect return from swap: %s", strerror(-rc));
934 printf("DV = %llx and %llx\n", dv1, dv2);
936 /* Finally, a good swap */
937 rc = llapi_fswap_layouts(fd1, fd2, dv1, dv2,
938 SWAP_LAYOUTS_CHECK_DV1 |
939 SWAP_LAYOUTS_CHECK_DV2);
940 ASSERTF(rc == 0, "incorrect return from swap: %s", strerror(-rc));
942 /* Check dataversion. */
943 rc = llapi_get_data_version(fd1, &new_dv1, LL_DV_RD_FLUSH);
945 "cannot get new dataversion for fd1: %s", strerror(-rc));
946 ASSERTF(dv1 != 0, "got dataversion 0 for fd1");
947 ASSERTF(dv1 != new_dv1, "got identical dataversion for fd1: %llx", dv1);
949 rc = llapi_get_data_version(fd2, &new_dv2, LL_DV_RD_FLUSH);
951 "cannot get new dataversion for fd2: %s", strerror(-rc));
952 ASSERTF(dv2 != 0, "got dataversion 0 for fd2");
953 ASSERTF(dv2 != new_dv2, "got identical dataversion for fd2: %llx", dv1);
955 printf("new DV = %llx and %llx\n", new_dv1, new_dv2);
957 /* Try again with same parameters. */
958 rc = llapi_fswap_layouts(fd1, fd2, dv1, dv2,
959 SWAP_LAYOUTS_CHECK_DV1 |
960 SWAP_LAYOUTS_CHECK_DV2);
961 ASSERTF(rc == -EAGAIN, "incorrect return from swap: %s", strerror(-rc));
966 /* Reopen the files and check again the dataversion */
967 name_fd1 = create_file_name("foo1");
968 fd1 = open(name_fd1, O_RDONLY);
970 "open failed for '%s': %s", name_fd1, strerror(errno));
972 rc = llapi_get_data_version(fd1, &new_new_dv1, LL_DV_RD_FLUSH);
973 ASSERTF(rc == 0, "cannot get dataversion for fd1: %s", strerror(-rc));
974 ASSERTF(new_new_dv1 != 0, "got dataversion 0 for fd1");
975 ASSERTF(new_dv1 == new_new_dv1,
976 "dataversion changed after re-opening: %llx and %llx",
977 new_dv1, new_new_dv1);
979 name_fd2 = create_file_name("foo2");
980 fd2 = open(name_fd2, O_RDONLY);
982 "open failed for '%s': %s", name_fd2, strerror(errno));
984 rc = llapi_get_data_version(fd2, &new_new_dv2, LL_DV_RD_FLUSH);
985 ASSERTF(rc == 0, "cannot get dataversion for fd2: %s", strerror(-rc));
986 ASSERTF(new_new_dv2 != 0, "got dataversion 0 for fd2");
987 ASSERTF(new_dv2 == new_new_dv2,
988 "dataversion changed after re-opening: %llx and %llx",
989 new_dv2, new_new_dv2);
991 printf("DV= %llx and %llx\n", new_new_dv1, new_new_dv2);
1000 /* swap group lock, no group */
1001 static void test50(void)
1006 size_t foo1_size = 2000;
1007 size_t foo2_size = 5000;
1009 rc = mkdir(mainpath, 0);
1010 ASSERTF(rc == 0, "mkdir failed for '%s': %s",
1011 mainpath, strerror(errno));
1013 fd1 = create_file("foo1", foo1_size, 'x');
1014 fd2 = create_file("foo2", foo2_size, 'y');
1016 rc = llapi_fswap_layouts_grouplock(fd1, fd2, 0, 0, 0, 0);
1017 ASSERTF(rc == 0, "llapi_fswap_layouts_grouplock failed: %s",
1024 /* swap group lock, with group */
1025 static void test51(void)
1030 size_t foo1_size = 2000;
1031 size_t foo2_size = 5000;
1033 rc = mkdir(mainpath, 0);
1034 ASSERTF(rc == 0, "mkdir failed for '%s': %s",
1035 mainpath, strerror(errno));
1037 fd1 = create_file("foo1", foo1_size, 'x');
1038 fd2 = create_file("foo2", foo2_size, 'y');
1040 rc = llapi_fswap_layouts_grouplock(fd1, fd2, 0, 0, 456789, 0);
1041 ASSERTF(rc == 0, "llapi_fswap_layouts_grouplock failed: %s",
1048 /* swap group lock, with existing group locks */
1049 static void test52(void)
1054 size_t foo1_size = 2000;
1055 size_t foo2_size = 5000;
1058 rc = mkdir(mainpath, 0);
1059 ASSERTF(rc == 0, "mkdir failed for '%s': %s",
1060 mainpath, strerror(errno));
1062 fd1 = create_file("foo1", foo1_size, 'x');
1063 fd2 = create_file("foo2", foo2_size, 'y');
1065 /* lock a descriptor, but swap without */
1066 rc = llapi_group_lock(fd1, gid);
1067 ASSERTF(rc == 0, "cannot lock 'foo1': %s", strerror(-rc));
1069 rc = llapi_fswap_layouts_grouplock(fd1, fd2, 0, 0, 0, 0);
1070 ASSERTF(rc == 0, "llapi_fswap_layouts_grouplock failed: %s",
1073 rc = llapi_group_unlock(fd1, gid);
1074 ASSERTF(rc == 0, "cannot unlock 'foo1': %s", strerror(-rc));
1080 /* Swap group lock, with existing group locks, on second descriptor */
1081 static void test53(void)
1086 size_t foo1_size = 2000;
1087 size_t foo2_size = 5000;
1090 rc = mkdir(mainpath, 0);
1091 ASSERTF(rc == 0, "mkdir failed for '%s': %s",
1092 mainpath, strerror(errno));
1094 fd1 = create_file("foo1", foo1_size, 'x');
1095 fd2 = create_file("foo2", foo2_size, 'y');
1097 /* lock a descriptor, but swap without */
1098 rc = llapi_group_lock(fd2, gid);
1099 ASSERTF(rc == 0, "cannot lock 'foo1': %s", strerror(-rc));
1101 rc = llapi_fswap_layouts_grouplock(fd1, fd2, 0, 0, 0, 0);
1102 ASSERTF(rc == 0, "llapi_fswap_layouts_grouplock failed: %s",
1105 rc = llapi_group_unlock(fd2, gid);
1106 ASSERTF(rc == 0, "cannot unlock 'foo1': %s", strerror(-rc));
1112 /* swap group lock, lock a descriptor, and try to swap with it. */
1113 static void test54(void)
1118 size_t foo1_size = 2000;
1119 size_t foo2_size = 5000;
1122 rc = mkdir(mainpath, 0);
1123 ASSERTF(rc == 0, "mkdir failed for '%s': %s",
1124 mainpath, strerror(errno));
1126 fd1 = create_file("foo1", foo1_size, 'x');
1127 fd2 = create_file("foo2", foo2_size, 'y');
1130 rc = llapi_group_lock(fd1, gid);
1131 ASSERTF(rc == 0, "cannot lock 'foo1': %s", strerror(-rc));
1133 rc = llapi_fswap_layouts_grouplock(fd1, fd2, 0, 0, gid, 0);
1134 ASSERTF(rc == -EINVAL, "llapi_fswap_layouts_grouplock failed: %s",
1137 rc = llapi_group_unlock(fd1, gid);
1138 ASSERTF(rc == 0, "cannot unlock 'foo1': %s", strerror(-rc));
1144 /* Swap group lock, lock a descriptor, and try to swap with it, on
1145 * second descriptor. */
1146 static void test55(void)
1151 size_t foo1_size = 2000;
1152 size_t foo2_size = 5000;
1155 rc = mkdir(mainpath, 0);
1156 ASSERTF(rc == 0, "mkdir failed for '%s': %s",
1157 mainpath, strerror(errno));
1159 fd1 = create_file("foo1", foo1_size, 'x');
1160 fd2 = create_file("foo2", foo2_size, 'y');
1162 rc = llapi_group_lock(fd2, gid);
1163 ASSERTF(rc == 0, "cannot lock 'foo1': %s", strerror(-rc));
1165 rc = llapi_fswap_layouts_grouplock(fd1, fd2, 0, 0, gid, 0);
1166 ASSERTF(rc == -EINVAL, "llapi_fswap_layouts_grouplock failed: %s",
1169 rc = llapi_group_unlock(fd2, gid);
1170 ASSERTF(rc == 0, "cannot unlock 'foo1': %s", strerror(-rc));
1176 /* Swap group lock, lock a descriptor, and try to swap with another
1178 static void test56(void)
1183 size_t foo1_size = 2000;
1184 size_t foo2_size = 5000;
1188 rc = mkdir(mainpath, 0);
1189 ASSERTF(rc == 0, "mkdir failed for '%s': %s",
1190 mainpath, strerror(errno));
1192 fd1 = create_file("foo1", foo1_size, 'x');
1193 fd2 = create_file("foo2", foo2_size, 'y');
1195 rc = llapi_group_lock(fd1, gid1);
1196 ASSERTF(rc == 0, "cannot lock 'foo1': %s", strerror(-rc));
1198 rc = llapi_group_lock(fd2, gid2);
1199 ASSERTF(rc == 0, "cannot lock 'foo1': %s", strerror(-rc));
1201 rc = llapi_fswap_layouts_grouplock(fd1, fd2, 0, 0, 0, 0);
1202 ASSERTF(rc == 0, "llapi_fswap_layouts_grouplock failed: %s",
1205 rc = llapi_group_unlock(fd1, gid1);
1206 ASSERTF(rc == 0, "cannot unlock 'foo1': %s", strerror(-rc));
1208 rc = llapi_group_unlock(fd2, gid2);
1209 ASSERTF(rc == 0, "cannot unlock 'foo2': %s", strerror(-rc));
1215 /* Swap group lock, lock both descriptor, and try to swap with another
1217 static void test57(void)
1222 size_t foo1_size = 2000;
1223 size_t foo2_size = 5000;
1227 rc = mkdir(mainpath, 0);
1228 ASSERTF(rc == 0, "mkdir failed for '%s': %s",
1229 mainpath, strerror(errno));
1231 fd1 = create_file("foo1", foo1_size, 'x');
1232 fd2 = create_file("foo2", foo2_size, 'y');
1234 rc = llapi_group_lock(fd1, gid1);
1235 ASSERTF(rc == 0, "cannot lock 'foo1': %s", strerror(-rc));
1237 rc = llapi_group_lock(fd2, gid2);
1238 ASSERTF(rc == 0, "cannot lock 'foo1': %s", strerror(-rc));
1240 rc = llapi_fswap_layouts_grouplock(fd1, fd2, 0, 0, gid1+gid2, 0);
1241 ASSERTF(rc == -EINVAL, "llapi_fswap_layouts_grouplock failed: %s",
1244 rc = llapi_group_unlock(fd1, gid1);
1245 ASSERTF(rc == 0, "cannot unlock 'foo1': %s", strerror(-rc));
1247 rc = llapi_group_unlock(fd2, gid2);
1248 ASSERTF(rc == 0, "cannot unlock 'foo2': %s", strerror(-rc));
1254 /* Swap group lock, lock both descriptor with same gid, and try to
1256 static void test58(void)
1261 size_t foo1_size = 2000;
1262 size_t foo2_size = 5000;
1265 rc = mkdir(mainpath, 0);
1266 ASSERTF(rc == 0, "mkdir failed for '%s': %s",
1267 mainpath, strerror(errno));
1269 fd1 = create_file("foo1", foo1_size, 'x');
1270 fd2 = create_file("foo2", foo2_size, 'y');
1272 rc = llapi_group_lock(fd1, gid);
1273 ASSERTF(rc == 0, "cannot lock 'foo1': %s", strerror(-rc));
1275 rc = llapi_group_lock(fd2, gid);
1276 ASSERTF(rc == 0, "cannot lock 'foo1': %s", strerror(-rc));
1278 rc = llapi_fswap_layouts_grouplock(fd1, fd2, 0, 0, gid, 0);
1279 ASSERTF(rc == -EINVAL, "llapi_fswap_layouts_grouplock failed: %s",
1282 rc = llapi_group_unlock(fd1, gid);
1283 ASSERTF(rc == 0, "cannot unlock 'foo1': %s", strerror(-rc));
1285 rc = llapi_group_unlock(fd2, gid);
1286 ASSERTF(rc == 0, "cannot unlock 'foo2': %s", strerror(-rc));
1292 /* Swap group lock, lock both descriptor with same gid, and swap with
1294 static void test59(void)
1299 size_t foo1_size = 2000;
1300 size_t foo2_size = 5000;
1303 rc = mkdir(mainpath, 0);
1304 ASSERTF(rc == 0, "mkdir failed for '%s': %s",
1305 mainpath, strerror(errno));
1307 fd1 = create_file("foo1", foo1_size, 'x');
1308 fd2 = create_file("foo2", foo2_size, 'y');
1310 rc = llapi_group_lock(fd1, gid);
1311 ASSERTF(rc == 0, "cannot lock 'foo1': %s", strerror(-rc));
1313 rc = llapi_group_lock(fd2, gid);
1314 ASSERTF(rc == 0, "cannot lock 'foo1': %s", strerror(-rc));
1316 rc = llapi_fswap_layouts_grouplock(fd1, fd2, 0, 0, 0, 0);
1317 ASSERTF(rc == 0, "llapi_fswap_layouts_grouplock failed: %s",
1320 rc = llapi_group_unlock(fd1, gid);
1321 ASSERTF(rc == 0, "cannot unlock 'foo1': %s", strerror(-rc));
1323 rc = llapi_group_unlock(fd2, gid);
1324 ASSERTF(rc == 0, "cannot unlock 'foo2': %s", strerror(-rc));
1330 static void usage(char *prog)
1332 fprintf(stderr, "Usage: %s [-d lustre_dir]\n", prog);
1336 static void process_args(int argc, char *argv[])
1340 while ((c = getopt(argc, argv, "d:")) != -1) {
1343 lustre_dir = optarg;
1347 fprintf(stderr, "Unknown option '%c'\n", optopt);
1354 int main(int argc, char *argv[])
1359 process_args(argc, argv);
1360 if (lustre_dir == NULL)
1361 lustre_dir = "/mnt/lustre";
1363 rc = llapi_search_mounts(lustre_dir, 0, fsmountdir, fsname);
1365 fprintf(stderr, "Error: '%s': not a Lustre filesystem\n",
1367 return EXIT_FAILURE;
1370 /* Play nice with Lustre test scripts. Non-line buffered output
1371 * stream under I/O redirection may appear incorrectly. */
1372 setvbuf(stdout, NULL, _IOLBF, 0);
1374 /* Create a test filename and reuse it. Remove possibly old files. */
1375 rc = snprintf(mainpath, sizeof(mainpath), "%s/%s", lustre_dir, maindir);
1376 ASSERTF(rc > 0 && rc < sizeof(mainpath), "invalid name for mainpath");
1405 return EXIT_SUCCESS;