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
23 * Copyright (c) 2016, 2017, Intel Corporation.
26 * These tests exercise the llapi_layout API which abstracts the layout
27 * of a Lustre file behind an opaque data type. They assume a Lustre
28 * file system with at least 2 OSTs and a pool containing at least the
29 * first 2 OSTs. For example,
31 * sudo lctl pool_new lustre.testpool
32 * sudo lctl pool_add lustre.testpool OST[0-1]
33 * gcc -Wall -g -Werror -o llapi_layout_test llapi_layout_test.c -llustreapi
34 * sudo ./llapi_layout_test
43 #include <sys/signal.h>
44 #include <sys/types.h>
46 #include <lustre/lustreapi.h>
52 #include <sys/ioctl.h>
54 #define ERROR(fmt, ...) \
55 fprintf(stderr, "%s: %s:%d: %s: " fmt "\n", \
56 program_invocation_short_name, __FILE__, __LINE__, \
57 __func__, ## __VA_ARGS__);
59 #define DIE(fmt, ...) \
61 ERROR(fmt, ## __VA_ARGS__); \
65 #define ASSERTF(cond, fmt, ...) \
68 DIE("assertion '%s' failed: "fmt, #cond, ## __VA_ARGS__);\
71 static char *lustre_dir;
72 static char *poolname;
73 static bool run_list_provided;
74 static int num_osts = -1;
76 static void usage(char *prog)
78 printf("Usage: %s [-d lustre_dir] [-p pool_name] [-o num_osts] "
79 "[-s $n,$m,... (skip tests)] [-t $n,$m,... (run tests)]\n",
85 #define T0_STRIPE_COUNT num_osts
86 #define T0_STRIPE_SIZE 1048576
87 #define T0_OST_OFFSET (num_osts - 1)
88 #define T0_DESC "Read/write layout attributes then create a file"
89 static void test0(void)
95 struct llapi_layout *layout = llapi_layout_alloc();
97 char mypool[LOV_MAXPOOLNAME + 1] = { '\0' };
99 ASSERTF(layout != NULL, "errno %d", errno);
101 snprintf(path, sizeof(path), "%s/%s", lustre_dir, T0FILE);
104 ASSERTF(rc >= 0 || errno == ENOENT, "errno = %d", errno);
107 rc = llapi_layout_stripe_count_set(layout, T0_STRIPE_COUNT);
108 ASSERTF(rc == 0, "errno = %d", errno);
109 rc = llapi_layout_stripe_count_get(layout, &count);
110 ASSERTF(rc == 0 && count == T0_STRIPE_COUNT, "%"PRIu64" != %d", count,
114 rc = llapi_layout_stripe_size_set(layout, T0_STRIPE_SIZE);
115 ASSERTF(rc == 0, "errno = %d", errno);
116 rc = llapi_layout_stripe_size_get(layout, &size);
117 ASSERTF(rc == 0 && size == T0_STRIPE_SIZE, "%"PRIu64" != %d", size,
121 rc = llapi_layout_pool_name_set(layout, poolname);
122 ASSERTF(rc == 0, "errno = %d", errno);
123 rc = llapi_layout_pool_name_get(layout, mypool, sizeof(mypool));
124 ASSERTF(rc == 0, "errno = %d", errno);
125 rc = strcmp(mypool, poolname);
126 ASSERTF(rc == 0, "%s != %s", mypool, poolname);
129 rc = llapi_layout_ost_index_set(layout, 0, T0_OST_OFFSET);
130 ASSERTF(rc == 0, "errno = %d", errno);
133 fd = llapi_layout_file_create(path, 0, 0660, layout);
134 ASSERTF(fd >= 0, "path = %s, errno = %d", path, errno);
136 ASSERTF(rc == 0, "errno = %d", errno);
137 llapi_layout_free(layout);
140 static void __test1_helper(struct llapi_layout *layout)
147 char mypool[LOV_MAXPOOLNAME + 1] = { '\0' };
149 rc = llapi_layout_stripe_count_get(layout, &count);
150 ASSERTF(count == T0_STRIPE_COUNT, "%"PRIu64" != %d", count,
153 rc = llapi_layout_stripe_size_get(layout, &size);
154 ASSERTF(size == T0_STRIPE_SIZE, "%"PRIu64" != %d", size,
157 rc = llapi_layout_pool_name_get(layout, mypool, sizeof(mypool));
158 ASSERTF(rc == 0, "errno = %d", errno);
159 rc = strcmp(mypool, poolname);
160 ASSERTF(rc == 0, "%s != %s", mypool, poolname);
162 rc = llapi_layout_ost_index_get(layout, 0, &ost0);
163 ASSERTF(rc == 0, "errno = %d", errno);
164 rc = llapi_layout_ost_index_get(layout, 1, &ost1);
165 ASSERTF(rc == 0, "errno = %d", errno);
166 ASSERTF(ost0 == T0_OST_OFFSET, "%"PRIu64" != %d", ost0, T0_OST_OFFSET);
167 ASSERTF(ost1 != ost0, "%"PRIu64" == %"PRIu64, ost0, ost1);
170 #define T1_DESC "Read test0 file by path and verify attributes"
171 static void test1(void)
175 snprintf(path, sizeof(path), "%s/%s", lustre_dir, T0FILE);
176 struct llapi_layout *layout = llapi_layout_get_by_path(path, 0);
178 ASSERTF(layout != NULL, "errno = %d", errno);
179 __test1_helper(layout);
180 llapi_layout_free(layout);
183 #define T2_DESC "Read test0 file by FD and verify attributes"
184 static void test2(void)
190 snprintf(path, sizeof(path), "%s/%s", lustre_dir, T0FILE);
192 fd = open(path, O_RDONLY);
193 ASSERTF(fd >= 0, "open(%s): errno = %d", path, errno);
195 struct llapi_layout *layout = llapi_layout_get_by_fd(fd, 0);
197 ASSERTF(layout != NULL, "errno = %d", errno);
200 ASSERTF(rc == 0, "close(%s): errno = %d", path, errno);
202 __test1_helper(layout);
203 llapi_layout_free(layout);
206 #define T3_DESC "Read test0 file by FID and verify attributes"
207 static void test3(void)
210 struct llapi_layout *layout;
215 snprintf(path, sizeof(path), "%s/%s", lustre_dir, T0FILE);
217 rc = llapi_path2fid(path, &fid);
218 ASSERTF(rc == 0, "rc = %d, errno = %d", rc, errno);
219 snprintf(fidstr, sizeof(fidstr), "0x%"PRIx64":0x%x:0x%x",
220 (uint64_t)fid.f_seq, fid.f_oid, fid.f_ver);
222 layout = llapi_layout_get_by_fid(path, &fid, 0);
223 ASSERTF(layout != NULL, "fidstr = %s, errno = %d", fidstr, errno);
225 __test1_helper(layout);
226 llapi_layout_free(layout);
230 #define T4_STRIPE_COUNT 2
231 #define T4_STRIPE_SIZE 2097152
232 #define T4_DESC "Verify compatibility with 'lfs setstripe'"
233 static void test4(void)
240 const char *lfs = getenv("LFS");
241 char mypool[LOV_MAXPOOLNAME + 1] = { '\0' };
242 char cmd[PATH_MAX + 128];
245 snprintf(path, sizeof(path), "%s/%s", lustre_dir, T4FILE);
248 lfs = "/usr/bin/lfs";
251 ASSERTF(rc == 0 || errno == ENOENT, "errno = %d", errno);
253 snprintf(cmd, sizeof(cmd), "%s setstripe %s %s -c %d -S %d %s", lfs,
254 strlen(poolname) > 0 ? "-p" : "", poolname, T4_STRIPE_COUNT,
255 T4_STRIPE_SIZE, path);
257 ASSERTF(rc == 0, "system(%s): exit status %d", cmd, WEXITSTATUS(rc));
260 struct llapi_layout *layout = llapi_layout_get_by_path(path, 0);
262 ASSERTF(layout != NULL, "errno = %d", errno);
264 rc = llapi_layout_stripe_count_get(layout, &count);
265 ASSERTF(count == T4_STRIPE_COUNT, "%"PRIu64" != %d", count,
268 rc = llapi_layout_stripe_size_get(layout, &size);
269 ASSERTF(size == T4_STRIPE_SIZE, "%"PRIu64" != %d", size,
272 rc = llapi_layout_pool_name_get(layout, mypool, sizeof(mypool));
273 ASSERTF(rc == 0, "errno = %d", errno);
274 rc = strcmp(mypool, poolname);
275 ASSERTF(rc == 0, "%s != %s", mypool, poolname);
277 rc = llapi_layout_ost_index_get(layout, 0, &ost0);
278 ASSERTF(rc == 0, "errno = %d", errno);
279 rc = llapi_layout_ost_index_get(layout, 1, &ost1);
280 ASSERTF(rc == 0, "errno = %d", errno);
281 ASSERTF(ost1 != ost0, "%"PRIu64" == %"PRIu64, ost0, ost1);
283 llapi_layout_free(layout);
287 #define T5_DESC "llapi_layout_get_by_path ENOENT handling"
288 static void test5(void)
292 struct llapi_layout *layout;
294 snprintf(path, sizeof(path), "%s/%s", lustre_dir, T5FILE);
297 ASSERTF(rc == 0 || errno == ENOENT, "errno = %d", errno);
300 layout = llapi_layout_get_by_path(path, 0);
301 ASSERTF(layout == NULL && errno == ENOENT, "errno = %d", errno);
304 #define T6_DESC "llapi_layout_get_by_fd EBADF handling"
305 static void test6(void)
308 struct llapi_layout *layout = llapi_layout_get_by_fd(9999, 0);
310 ASSERTF(layout == NULL && errno == EBADF, "errno = %d", errno);
314 #define T7_DESC "llapi_layout_get_by_path EACCES handling"
315 static void test7(void)
319 uid_t myuid = getuid();
321 const char *runas = getenv("RUNAS_ID");
325 snprintf(path, sizeof(path), "%s/%s", lustre_dir, T7FILE);
326 ASSERTF(myuid == 0, "myuid = %d", myuid); /* Need root for this test. */
328 /* Create file as root */
330 ASSERTF(rc == 0 || errno == ENOENT, "errno = %d", errno);
332 fd = open(path, O_CREAT, 0400);
333 ASSERTF(fd > 0, "errno = %d", errno);
335 ASSERTF(rc == 0, "errno = %d", errno);
337 /* Become unprivileged user */
340 ASSERTF(uid != 0, "runas = %s", runas);
342 pw = getpwnam("nobody");
343 ASSERTF(pw != NULL, "errno = %d", errno);
347 ASSERTF(rc == 0, "errno = %d", errno);
349 struct llapi_layout *layout = llapi_layout_get_by_path(path, 0);
351 ASSERTF(layout == NULL && errno == EACCES, "errno = %d", errno);
353 ASSERTF(rc == 0, "errno = %d", errno);
356 /* llapi_layout_get_by_path() returns default layout for file with no
357 * striping attributes.
360 #define T8_DESC "llapi_layout_get_by_path ENODATA handling"
361 static void test8(void)
365 struct llapi_layout *layout;
371 snprintf(path, sizeof(path), "%s/%s", lustre_dir, T8FILE);
374 ASSERTF(rc >= 0 || errno == ENOENT, "errno = %d", errno);
375 fd = open(path, O_CREAT, 0640);
376 ASSERTF(fd >= 0, "errno = %d", errno);
378 ASSERTF(rc == 0, "errno = %d", errno);
380 layout = llapi_layout_get_by_path(path, 0);
381 ASSERTF(layout != NULL, "errno = %d\n", errno);
383 rc = llapi_layout_stripe_count_get(layout, &count);
384 ASSERTF(rc == 0, "errno = %d\n", errno);
385 ASSERTF(count == LLAPI_LAYOUT_DEFAULT, "count = %"PRIu64"\n", count);
387 rc = llapi_layout_stripe_size_get(layout, &size);
388 ASSERTF(rc == 0, "errno = %d\n", errno);
389 ASSERTF(size == LLAPI_LAYOUT_DEFAULT, "size = %"PRIu64"\n", size);
391 rc = llapi_layout_pattern_get(layout, &pattern);
392 ASSERTF(rc == 0, "errno = %d\n", errno);
393 ASSERTF(pattern == LLAPI_LAYOUT_DEFAULT, "pattern = %"PRIu64"\n",
396 llapi_layout_free(layout);
399 /* Verify llapi_layout_patter_set() return values for various inputs. */
400 #define T9_DESC "verify llapi_layout_pattern_set() return values"
401 static void test9(void)
403 struct llapi_layout *layout;
406 layout = llapi_layout_alloc();
407 ASSERTF(layout != NULL, "errno = %d\n", errno);
410 rc = llapi_layout_pattern_set(layout, LLAPI_LAYOUT_INVALID);
411 ASSERTF(rc == -1 && errno == EOPNOTSUPP, "rc = %d, errno = %d", rc,
415 rc = llapi_layout_pattern_set(NULL, LLAPI_LAYOUT_DEFAULT);
416 ASSERTF(rc == -1 && errno == EINVAL, "rc = %d, errno = %d", rc,
420 rc = llapi_layout_pattern_set(layout, LLAPI_LAYOUT_DEFAULT);
421 ASSERTF(rc == 0, "rc = %d, errno = %d", rc, errno);
424 rc = llapi_layout_pattern_set(layout, LLAPI_LAYOUT_RAID0);
425 ASSERTF(rc == 0, "rc = %d, errno = %d", rc, errno);
427 llapi_layout_free(layout);
430 /* Verify stripe_count interfaces return errors as expected */
431 #define T10_DESC "stripe_count error handling"
432 static void test10(void)
436 struct llapi_layout *layout;
438 layout = llapi_layout_alloc();
439 ASSERTF(layout != NULL, "errno = %d", errno);
441 /* invalid stripe count */
443 rc = llapi_layout_stripe_count_set(layout, LLAPI_LAYOUT_INVALID);
444 ASSERTF(rc == -1 && errno == EINVAL, "rc = %d, errno = %d", rc, errno);
447 rc = llapi_layout_stripe_count_set(layout, -1);
448 ASSERTF(rc == -1 && errno == EINVAL, "rc = %d, errno = %d", rc, errno);
452 rc = llapi_layout_stripe_count_set(NULL, 2);
453 ASSERTF(rc == -1 && errno == EINVAL, "rc = %d, errno = %d", rc, errno);
457 rc = llapi_layout_stripe_count_get(NULL, &count);
458 ASSERTF(rc == -1 && errno == EINVAL, "rc = %d, errno = %d", rc, errno);
462 rc = llapi_layout_stripe_count_get(layout, NULL);
463 ASSERTF(rc == -1 && errno == EINVAL, "rc = %d, errno = %d", rc, errno);
465 /* stripe count too large */
467 rc = llapi_layout_stripe_count_set(layout, LOV_MAX_STRIPE_COUNT + 1);
468 ASSERTF(rc == -1 && errno == EINVAL, "rc = %d, errno = %d", rc, errno);
469 llapi_layout_free(layout);
472 /* Verify stripe_size interfaces return errors as expected */
473 #define T11_DESC "stripe_size error handling"
474 static void test11(void)
478 struct llapi_layout *layout;
480 layout = llapi_layout_alloc();
481 ASSERTF(layout != NULL, "errno = %d", errno);
483 /* negative stripe size */
485 rc = llapi_layout_stripe_size_set(layout, -1);
486 ASSERTF(rc == -1 && errno == EINVAL, "rc = %d, errno = %d", rc, errno);
488 /* invalid stripe size */
490 rc = llapi_layout_stripe_size_set(layout, LLAPI_LAYOUT_INVALID);
491 ASSERTF(rc == -1 && errno == EINVAL, "rc = %d, errno = %d", rc, errno);
493 /* stripe size too big */
495 rc = llapi_layout_stripe_size_set(layout, (1ULL << 33));
496 ASSERTF(rc == -1 && errno == EINVAL, "rc = %d, errno = %d", rc, errno);
500 rc = llapi_layout_stripe_size_set(NULL, 1048576);
501 ASSERTF(rc == -1 && errno == EINVAL, "rc = %d, errno = %d", rc, errno);
504 rc = llapi_layout_stripe_size_get(NULL, &size);
505 ASSERTF(rc == -1 && errno == EINVAL, "rc = %d, errno = %d", rc, errno);
509 rc = llapi_layout_stripe_size_get(layout, NULL);
510 ASSERTF(rc == -1 && errno == EINVAL, "rc = %d, errno = %d", rc, errno);
512 llapi_layout_free(layout);
515 /* Verify pool_name interfaces return errors as expected */
516 #define T12_DESC "pool_name error handling"
517 static void test12(void)
520 struct llapi_layout *layout;
521 char mypool[LOV_MAXPOOLNAME + 1] = { '\0' };
523 layout = llapi_layout_alloc();
524 ASSERTF(layout != NULL, "errno = %d", errno);
528 rc = llapi_layout_pool_name_set(NULL, "foo");
529 ASSERTF(rc == -1 && errno == EINVAL, "rc = %d, errno = %d", rc, errno);
533 rc = llapi_layout_pool_name_set(layout, NULL);
534 ASSERTF(rc == -1 && errno == EINVAL, "rc = %d, errno = %d", rc, errno);
538 rc = llapi_layout_pool_name_get(NULL, mypool, sizeof(mypool));
539 ASSERTF(errno == EINVAL, "poolname = %s, errno = %d", poolname, errno);
543 rc = llapi_layout_pool_name_get(layout, NULL, sizeof(mypool));
544 ASSERTF(errno == EINVAL, "poolname = %s, errno = %d", poolname, errno);
546 /* Pool name too long*/
548 rc = llapi_layout_pool_name_set(layout, "0123456789abcdef");
549 ASSERTF(rc == -1 && errno == EINVAL, "rc = %d, errno = %d", rc, errno);
551 llapi_layout_free(layout);
554 /* Verify ost_index interface returns errors as expected */
555 #define T13FILE "t13"
556 #define T13_STRIPE_COUNT 2
557 #define T13_DESC "ost_index error handling"
558 static void test13(void)
563 struct llapi_layout *layout;
566 snprintf(path, sizeof(path), "%s/%s", lustre_dir, T13FILE);
568 layout = llapi_layout_alloc();
569 ASSERTF(layout != NULL, "errno = %d", errno);
571 /* invalid OST index */
573 rc = llapi_layout_ost_index_set(layout, 0, LLAPI_LAYOUT_INVALID);
574 ASSERTF(rc == -1 && errno == EINVAL, "rc = %d, errno = %d", rc, errno);
577 rc = llapi_layout_ost_index_set(layout, 0, -1);
578 ASSERTF(rc == -1 && errno == EINVAL, "rc = %d, errno = %d", rc, errno);
582 rc = llapi_layout_ost_index_set(NULL, 0, 1);
583 ASSERTF(rc == -1 && errno == EINVAL, "rc = %d, errno = %d", rc, errno);
586 rc = llapi_layout_ost_index_get(NULL, 0, &idx);
587 ASSERTF(rc == -1 && errno == EINVAL, "rc = %d, errno = %d", rc, errno);
591 rc = llapi_layout_ost_index_get(layout, 0, NULL);
592 ASSERTF(rc == -1 && errno == EINVAL, "rc = %d, errno = %d", rc, errno);
594 /* Layout not read from file so has no OST data. */
596 rc = llapi_layout_stripe_count_set(layout, T13_STRIPE_COUNT);
597 ASSERTF(rc == 0, "errno = %d", errno);
598 rc = llapi_layout_ost_index_get(layout, 0, &idx);
599 ASSERTF(rc == -1 && errno == EINVAL, "rc = %d, errno = %d", rc, errno);
601 /* n greater than stripe count*/
603 ASSERTF(rc >= 0 || errno == ENOENT, "errno = %d", errno);
604 rc = llapi_layout_stripe_count_set(layout, T13_STRIPE_COUNT);
605 ASSERTF(rc == 0, "errno = %d", errno);
606 fd = llapi_layout_file_create(path, 0, 0644, layout);
607 ASSERTF(fd >= 0, "errno = %d", errno);
609 ASSERTF(rc == 0, "errno = %d", errno);
610 llapi_layout_free(layout);
612 layout = llapi_layout_get_by_path(path, 0);
613 ASSERTF(layout != NULL, "errno = %d", errno);
615 rc = llapi_layout_ost_index_get(layout, T13_STRIPE_COUNT + 1, &idx);
616 ASSERTF(rc == -1 && errno == EINVAL, "rc = %d, errno = %d", rc, errno);
618 llapi_layout_free(layout);
621 /* Verify llapi_layout_file_create() returns errors as expected */
622 #define T14_DESC "llapi_layout_file_create error handling"
623 static void test14(void)
626 struct llapi_layout *layout = llapi_layout_alloc();
630 rc = llapi_layout_file_create(NULL, 0, 0, layout);
631 ASSERTF(rc == -1 && errno == EINVAL, "rc = %d, errno = %d", rc, errno);
633 llapi_layout_free(layout);
636 /* Can't change striping attributes of existing file. */
637 #define T15FILE "t15"
638 #define T15_STRIPE_COUNT 2
639 #define T15_DESC "Can't change striping attributes of existing file"
640 static void test15(void)
645 struct llapi_layout *layout;
648 snprintf(path, sizeof(path), "%s/%s", lustre_dir, T15FILE);
651 ASSERTF(rc >= 0 || errno == ENOENT, "errno = %d", errno);
653 layout = llapi_layout_alloc();
654 ASSERTF(layout != NULL, "errno = %d", errno);
655 rc = llapi_layout_stripe_count_set(layout, T15_STRIPE_COUNT);
656 ASSERTF(rc == 0, "errno = %d", errno);
659 fd = llapi_layout_file_create(path, 0, 0640, layout);
660 ASSERTF(fd >= 0, "fd = %d, errno = %d", fd, errno);
662 ASSERTF(rc == 0, "errno = %d", errno);
664 rc = llapi_layout_stripe_count_set(layout, T15_STRIPE_COUNT - 1);
666 fd = llapi_layout_file_open(path, 0, 0640, layout);
667 ASSERTF(fd >= 0, "fd = %d, errno = %d", fd, errno);
669 ASSERTF(rc == 0, "errno = %d", errno);
670 llapi_layout_free(layout);
672 layout = llapi_layout_get_by_path(path, 0);
673 ASSERTF(layout != NULL, "errno = %d", errno);
674 rc = llapi_layout_stripe_count_get(layout, &count);
675 ASSERTF(rc == 0 && count == T15_STRIPE_COUNT,
676 "rc = %d, %"PRIu64" != %d", rc, count, T15_STRIPE_COUNT);
677 llapi_layout_free(layout);
680 /* Default stripe attributes are applied as expected. */
681 #define T16FILE "t16"
682 #define T16_DESC "Default stripe attributes are applied as expected"
683 static void test16(void)
687 struct llapi_layout *deflayout;
688 struct llapi_layout *filelayout;
695 snprintf(path, sizeof(path), "%s/%s", lustre_dir, T16FILE);
698 ASSERTF(rc == 0 || errno == ENOENT, "errno = %d", errno);
700 deflayout = llapi_layout_get_by_path(lustre_dir, LAYOUT_GET_EXPECTED);
701 ASSERTF(deflayout != NULL, "errno = %d", errno);
702 rc = llapi_layout_stripe_size_get(deflayout, &dsize);
703 ASSERTF(rc == 0, "errno = %d", errno);
704 rc = llapi_layout_stripe_count_get(deflayout, &dcount);
705 ASSERTF(rc == 0, "errno = %d", errno);
707 /* First, with a default struct llapi_layout */
708 filelayout = llapi_layout_alloc();
709 ASSERTF(filelayout != NULL, "errno = %d", errno);
711 fd = llapi_layout_file_create(path, 0, 0640, filelayout);
712 ASSERTF(fd >= 0, "errno = %d", errno);
715 ASSERTF(rc == 0, "errno = %d", errno);
717 llapi_layout_free(filelayout);
719 filelayout = llapi_layout_get_by_path(path, 0);
720 ASSERTF(filelayout != NULL, "errno = %d", errno);
722 rc = llapi_layout_stripe_count_get(filelayout, &fcount);
723 ASSERTF(rc == 0, "errno = %d", errno);
724 ASSERTF(fcount == dcount || dcount == LLAPI_LAYOUT_DEFAULT ||
725 dcount == LLAPI_LAYOUT_WIDE,
726 "%"PRIu64" != %"PRIu64, fcount, dcount);
728 rc = llapi_layout_stripe_size_get(filelayout, &fsize);
729 ASSERTF(rc == 0, "errno = %d", errno);
730 ASSERTF(fsize == dsize, "%"PRIu64" != %"PRIu64, fsize, dsize);
732 /* NULL layout also implies default layout */
734 ASSERTF(rc == 0 || errno == ENOENT, "errno = %d", errno);
736 fd = llapi_layout_file_create(path, 0, 0640, filelayout);
737 ASSERTF(fd >= 0, "errno = %d", errno);
739 ASSERTF(rc == 0, "errno = %d", errno);
740 filelayout = llapi_layout_get_by_path(path, 0);
741 ASSERTF(filelayout != NULL, "errno = %d", errno);
743 rc = llapi_layout_stripe_count_get(filelayout, &fcount);
744 ASSERTF(rc == 0, "errno = %d", errno);
745 rc = llapi_layout_stripe_size_get(filelayout, &fsize);
746 ASSERTF(rc == 0, "errno = %d", errno);
747 ASSERTF(fcount == dcount || dcount == LLAPI_LAYOUT_DEFAULT ||
748 dcount == LLAPI_LAYOUT_WIDE,
749 "%"PRIu64" != %"PRIu64, fcount, dcount);
750 ASSERTF(fsize == dsize, "%"PRIu64" != %"PRIu64, fsize, dsize);
752 llapi_layout_free(filelayout);
753 llapi_layout_free(deflayout);
756 /* Setting stripe count to LLAPI_LAYOUT_WIDE uses all available OSTs. */
757 #define T17FILE "t17"
758 #define T17_DESC "LLAPI_LAYOUT_WIDE is honored"
759 static void test17(void)
764 uint64_t osts_layout;
765 struct llapi_layout *layout;
768 snprintf(path, sizeof(path), "%s/%s", lustre_dir, T17FILE);
771 ASSERTF(rc == 0 || errno == ENOENT, "errno = %d", errno);
772 layout = llapi_layout_alloc();
773 ASSERTF(layout != NULL, "errno = %d", errno);
774 rc = llapi_layout_stripe_count_set(layout, LLAPI_LAYOUT_WIDE);
775 ASSERTF(rc == 0, "errno = %d", errno);
776 fd = llapi_layout_file_create(path, 0, 0640, layout);
777 ASSERTF(fd >= 0, "errno = %d", errno);
779 ASSERTF(rc == 0, "errno = %d", errno);
780 llapi_layout_free(layout);
782 /* Get number of available OSTs */
783 fd = open(path, O_RDONLY);
784 ASSERTF(fd >= 0, "errno = %d", errno);
785 rc = llapi_lov_get_uuids(fd, NULL, &osts_all);
786 ASSERTF(rc == 0, "rc = %d, errno = %d", rc, errno);
788 ASSERTF(rc == 0, "errno = %d", errno);
790 layout = llapi_layout_get_by_path(path, 0);
791 ASSERTF(layout != NULL, "errno = %d", errno);
792 rc = llapi_layout_stripe_count_get(layout, &osts_layout);
793 ASSERTF(osts_layout == osts_all, "%"PRIu64" != %d", osts_layout,
796 llapi_layout_free(layout);
799 /* Setting pool with "fsname.pool" notation. */
800 #define T18FILE "t18"
801 #define T18_DESC "Setting pool with fsname.pool notation"
802 static void test18(void)
806 struct llapi_layout *layout = llapi_layout_alloc();
808 char pool[LOV_MAXPOOLNAME*2 + 1];
809 char mypool[LOV_MAXPOOLNAME + 1] = { '\0' };
811 snprintf(pool, sizeof(pool), "lustre.%s", poolname);
813 snprintf(path, sizeof(path), "%s/%s", lustre_dir, T18FILE);
815 ASSERTF(layout != NULL, "errno = %d", errno);
818 ASSERTF(rc == 0 || errno == ENOENT, "errno = %d", errno);
820 rc = llapi_layout_pool_name_set(layout, pool);
821 ASSERTF(rc == 0, "errno = %d", errno);
823 rc = llapi_layout_pool_name_get(layout, mypool, sizeof(mypool));
824 ASSERTF(rc == 0, "errno = %d", errno);
825 rc = strcmp(mypool, poolname);
826 ASSERTF(rc == 0, "%s != %s", mypool, poolname);
827 fd = llapi_layout_file_create(path, 0, 0640, layout);
828 ASSERTF(fd >= 0, "errno = %d", errno);
830 ASSERTF(rc == 0, "errno = %d", errno);
832 llapi_layout_free(layout);
834 layout = llapi_layout_get_by_path(path, 0);
835 ASSERTF(layout != NULL, "errno = %d", errno);
836 rc = llapi_layout_pool_name_get(layout, mypool, sizeof(mypool));
837 ASSERTF(rc == 0, "errno = %d", errno);
838 rc = strcmp(mypool, poolname);
839 ASSERTF(rc == 0, "%s != %s", mypool, poolname);
840 llapi_layout_free(layout);
843 #define T19_DESC "Maximum length pool name is NULL-terminated"
844 static void test19(void)
846 struct llapi_layout *layout;
847 char *name = "0123456789abcde";
848 char mypool[LOV_MAXPOOLNAME + 1] = { '\0' };
851 layout = llapi_layout_alloc();
852 ASSERTF(layout != NULL, "errno = %d", errno);
853 rc = llapi_layout_pool_name_set(layout, name);
854 ASSERTF(rc == 0, "errno = %d", errno);
855 rc = llapi_layout_pool_name_get(layout, mypool, sizeof(mypool));
856 ASSERTF(strlen(name) == strlen(mypool), "name = %s, str = %s", name,
858 llapi_layout_free(layout);
861 #define T20FILE "t20"
862 #define T20_DESC "LLAPI_LAYOUT_DEFAULT is honored"
863 static void test20(void)
867 struct llapi_layout *deflayout;
868 struct llapi_layout *filelayout;
875 snprintf(path, sizeof(path), "%s/%s", lustre_dir, T20FILE);
878 ASSERTF(rc == 0 || errno == ENOENT, "errno = %d", errno);
880 filelayout = llapi_layout_alloc();
881 ASSERTF(filelayout != NULL, "errno = %d", errno);
883 rc = llapi_layout_stripe_size_set(filelayout, LLAPI_LAYOUT_DEFAULT);
884 ASSERTF(rc == 0, "rc = %d, errno = %d", rc, errno);
886 rc = llapi_layout_stripe_count_set(filelayout, LLAPI_LAYOUT_DEFAULT);
887 ASSERTF(rc == 0, "rc = %d, errno = %d", rc, errno);
889 fd = llapi_layout_file_create(path, 0, 0640, filelayout);
890 ASSERTF(fd >= 0, "errno = %d", errno);
893 ASSERTF(rc == 0, "errno = %d", errno);
895 llapi_layout_free(filelayout);
897 deflayout = llapi_layout_get_by_path(lustre_dir, LAYOUT_GET_EXPECTED);
898 ASSERTF(deflayout != NULL, "errno = %d", errno);
900 filelayout = llapi_layout_get_by_path(path, 0);
901 ASSERTF(filelayout != NULL, "errno = %d", errno);
903 rc = llapi_layout_stripe_count_get(filelayout, &fcount);
904 ASSERTF(rc == 0, "errno = %d", errno);
905 rc = llapi_layout_stripe_count_get(deflayout, &dcount);
906 ASSERTF(rc == 0, "errno = %d", errno);
907 ASSERTF(fcount == dcount || dcount == LLAPI_LAYOUT_DEFAULT ||
908 dcount == LLAPI_LAYOUT_WIDE,
909 "%"PRIu64" != %"PRIu64, fcount, dcount);
911 rc = llapi_layout_stripe_size_get(filelayout, &fsize);
912 ASSERTF(rc == 0, "errno = %d", errno);
913 rc = llapi_layout_stripe_size_get(deflayout, &dsize);
914 ASSERTF(rc == 0, "errno = %d", errno);
915 ASSERTF(fsize == dsize, "%"PRIu64" != %"PRIu64, fsize, dsize);
917 llapi_layout_free(filelayout);
918 llapi_layout_free(deflayout);
921 #define T21_DESC "llapi_layout_file_create fails for non-Lustre file"
922 static void test21(void)
924 struct llapi_layout *layout;
925 char template[PATH_MAX];
929 snprintf(template, sizeof(template), "%s/XXXXXX", P_tmpdir);
930 fd = mkstemp(template);
931 ASSERTF(fd >= 0, "template = %s, errno = %d", template, errno);
933 ASSERTF(rc == 0, "errno = %d", fd);
934 rc = unlink(template);
935 ASSERTF(rc == 0, "errno = %d", errno);
937 layout = llapi_layout_alloc();
938 ASSERTF(layout != NULL, "errno = %d", errno);
940 fd = llapi_layout_file_create(template, 0, 0640, layout);
941 ASSERTF(fd == -1 && errno == ENOTTY,
942 "fd = %d, errno = %d, template = %s", fd, errno, template);
943 llapi_layout_free(layout);
946 #define T22FILE "t22"
947 #define T22_DESC "llapi_layout_file_create applied mode correctly"
948 static void test22(void)
954 mode_t mode_in = 0640;
958 snprintf(path, sizeof(path), "%s/%s", lustre_dir, T22FILE);
961 ASSERTF(rc == 0 || errno == ENOENT, "errno = %d", errno);
963 umask_orig = umask(0022);
965 fd = llapi_layout_file_create(path, 0, mode_in, NULL);
966 ASSERTF(fd >= 0, "errno = %d", errno);
968 (void) umask(umask_orig);
971 ASSERTF(rc == 0, "errno = %d", errno);
974 ASSERTF(rc == 0, "errno = %d", fd);
976 mode_out = st.st_mode & ~S_IFMT;
977 ASSERTF(mode_in == mode_out, "%o != %o", mode_in, mode_out);
980 #define T23_DESC "llapi_layout_get_by_path fails for non-Lustre file"
981 static void test23(void)
983 struct llapi_layout *layout;
984 char template[PATH_MAX];
988 snprintf(template, sizeof(template), "%s/XXXXXX", P_tmpdir);
989 fd = mkstemp(template);
990 ASSERTF(fd >= 0, "template = %s, errno = %d", template, errno);
992 ASSERTF(rc == 0, "errno = %d", fd);
994 layout = llapi_layout_get_by_path(template, 0);
995 ASSERTF(layout == NULL && errno == ENOTTY,
996 "errno = %d, template = %s", errno, template);
998 rc = unlink(template);
999 ASSERTF(rc == 0, "errno = %d", errno);
1002 /* llapi_layout_get_by_path(path, LAYOUT_GET_EXPECTED) returns expected layout
1003 * for file with unspecified layout.
1005 #define T24FILE "t24"
1006 #define T24_DESC "LAYOUT_GET_EXPECTED works with existing file"
1007 static void test24(void)
1011 struct llapi_layout *layout;
1015 char path[PATH_MAX];
1017 snprintf(path, sizeof(path), "%s/%s", lustre_dir, T24FILE);
1020 ASSERTF(rc >= 0 || errno == ENOENT, "errno = %d", errno);
1021 fd = open(path, O_CREAT, 0640);
1022 ASSERTF(fd >= 0, "errno = %d", errno);
1024 ASSERTF(rc == 0, "errno = %d", errno);
1026 layout = llapi_layout_get_by_path(path, LAYOUT_GET_EXPECTED);
1027 ASSERTF(layout != NULL, "errno = %d\n", errno);
1029 rc = llapi_layout_stripe_count_get(layout, &count);
1030 ASSERTF(rc == 0, "errno = %d\n", errno);
1031 ASSERTF(count != LLAPI_LAYOUT_DEFAULT, "expected literal value");
1033 rc = llapi_layout_stripe_size_get(layout, &size);
1034 ASSERTF(rc == 0, "errno = %d\n", errno);
1035 ASSERTF(size != LLAPI_LAYOUT_DEFAULT, "expected literal value");
1037 rc = llapi_layout_pattern_get(layout, &pattern);
1038 ASSERTF(rc == 0, "errno = %d\n", errno);
1039 ASSERTF(pattern != LLAPI_LAYOUT_DEFAULT, "expected literal value");
1041 llapi_layout_free(layout);
1044 /* llapi_layout_get_by_path(path, LAYOUT_GET_EXPECTED) returns expected layout
1045 * for directory with unspecified layout.
1047 #define T25DIR "d25"
1048 #define T25_DESC "LAYOUT_GET_EXPECTED works with directory"
1049 static void test25(void)
1052 struct llapi_layout *layout;
1058 snprintf(dir, sizeof(dir), "%s/%s", lustre_dir, T25DIR);
1061 ASSERTF(rc >= 0 || errno == ENOENT, "errno = %d", errno);
1062 rc = mkdir(dir, 0750);
1063 ASSERTF(rc == 0, "errno = %d", errno);
1065 layout = llapi_layout_get_by_path(dir, LAYOUT_GET_EXPECTED);
1066 ASSERTF(layout != NULL, "errno = %d\n", errno);
1068 rc = llapi_layout_stripe_count_get(layout, &count);
1069 ASSERTF(rc == 0, "errno = %d\n", errno);
1070 ASSERTF(count != LLAPI_LAYOUT_DEFAULT, "expected literal value");
1072 rc = llapi_layout_stripe_size_get(layout, &size);
1073 ASSERTF(rc == 0, "errno = %d\n", errno);
1074 ASSERTF(size != LLAPI_LAYOUT_DEFAULT, "expected literal value");
1076 rc = llapi_layout_pattern_get(layout, &pattern);
1077 ASSERTF(rc == 0, "errno = %d\n", errno);
1078 ASSERTF(pattern != LLAPI_LAYOUT_DEFAULT, "expected literal value");
1080 llapi_layout_free(layout);
1083 /* llapi_layout_get_by_path(path, LAYOUT_GET_EXPECTED) correctly combines
1084 * specified attributes of parent directory with attributes filesystem root.
1086 #define T26DIR "d26"
1087 #define T26_DESC "LAYOUT_GET_EXPECTED partially specified parent"
1088 #define T26_STRIPE_SIZE (1048576 * 4)
1089 static void test26(void)
1092 struct llapi_layout *layout;
1093 const char *lfs = getenv("LFS");
1098 char cmd[PATH_MAX + 64];
1100 snprintf(dir, sizeof(dir), "%s/%s", lustre_dir, T26DIR);
1102 ASSERTF(rc >= 0 || errno == ENOENT, "errno = %d", errno);
1103 rc = mkdir(dir, 0750);
1104 ASSERTF(rc == 0, "errno = %d", errno);
1107 lfs = "/usr/bin/lfs";
1109 snprintf(cmd, sizeof(cmd), "%s setstripe -S %d %s", lfs,
1110 T26_STRIPE_SIZE, dir);
1112 ASSERTF(rc == 0, "system(%s): exit status %d", cmd, WEXITSTATUS(rc));
1114 layout = llapi_layout_get_by_path(dir, LAYOUT_GET_EXPECTED);
1115 ASSERTF(layout != NULL, "errno = %d\n", errno);
1117 rc = llapi_layout_stripe_count_get(layout, &count);
1118 ASSERTF(rc == 0, "errno = %d\n", errno);
1119 ASSERTF(count != LLAPI_LAYOUT_DEFAULT, "expected literal value");
1121 rc = llapi_layout_stripe_size_get(layout, &size);
1122 ASSERTF(rc == 0, "errno = %d\n", errno);
1123 ASSERTF(size == T26_STRIPE_SIZE, "size = %"PRIu64, size);
1125 rc = llapi_layout_pattern_get(layout, &pattern);
1126 ASSERTF(rc == 0, "errno = %d\n", errno);
1127 ASSERTF(pattern != LLAPI_LAYOUT_DEFAULT, "expected literal value");
1129 llapi_layout_free(layout);
1132 /* llapi_layout_get_by_path(path, LAYOUT_GET_EXPECTED) work with
1133 * non existing file.
1135 #define T27DIR "d27"
1136 #define T27_DESC "LAYOUT_GET_EXPECTED with non existing file"
1137 #define T27_STRIPE_SIZE (1048576 * 3)
1138 static void test27(void)
1141 struct llapi_layout *layout;
1142 const char *lfs = getenv("LFS");
1146 char dirpath[PATH_MAX + 128];
1147 char filepath[PATH_MAX * 2];
1148 char cmd[PATH_MAX * 2];
1150 snprintf(dirpath, sizeof(dirpath) - 1, "%s/%s", lustre_dir, T27DIR);
1151 snprintf(filepath, sizeof(filepath), "%s/nonesuch", dirpath);
1153 rc = rmdir(dirpath);
1154 ASSERTF(rc >= 0 || errno == ENOENT, "errno = %d", errno);
1155 rc = mkdir(dirpath, 0750);
1156 ASSERTF(rc == 0, "errno = %d", errno);
1159 lfs = "/usr/bin/lfs";
1161 snprintf(cmd, sizeof(cmd), "%s setstripe -S %d %s", lfs,
1162 T27_STRIPE_SIZE, dirpath);
1164 ASSERTF(rc == 0, "system(%s): exit status %d", cmd, WEXITSTATUS(rc));
1166 layout = llapi_layout_get_by_path(filepath, LAYOUT_GET_EXPECTED);
1167 ASSERTF(layout != NULL, "errno = %d\n", errno);
1169 rc = llapi_layout_stripe_count_get(layout, &count);
1170 ASSERTF(rc == 0, "errno = %d\n", errno);
1171 ASSERTF(count != LLAPI_LAYOUT_DEFAULT, "expected literal value");
1173 rc = llapi_layout_stripe_size_get(layout, &size);
1174 ASSERTF(rc == 0, "errno = %d\n", errno);
1175 ASSERTF(size == T27_STRIPE_SIZE, "size = %"PRIu64, size);
1177 rc = llapi_layout_pattern_get(layout, &pattern);
1178 ASSERTF(rc == 0, "errno = %d\n", errno);
1179 ASSERTF(pattern != LLAPI_LAYOUT_DEFAULT, "expected literal value");
1181 llapi_layout_free(layout);
1184 /* llapi_layout_stripe_count_get returns LLAPI_LAYOUT_WIDE for a directory
1185 * with a stripe_count of -1.
1187 #define T28DIR "d28"
1188 #define T28_DESC "LLAPI_LAYOUT_WIDE returned as expected"
1189 static void test28(void)
1192 struct llapi_layout *layout;
1193 const char *lfs = getenv("LFS");
1195 char dirpath[PATH_MAX];
1196 char cmd[PATH_MAX + 64];
1198 snprintf(dirpath, sizeof(dirpath), "%s/%s", lustre_dir, T28DIR);
1200 rc = rmdir(dirpath);
1201 ASSERTF(rc >= 0 || errno == ENOENT, "errno = %d", errno);
1202 rc = mkdir(dirpath, 0750);
1203 ASSERTF(rc == 0, "errno = %d", errno);
1206 lfs = "/usr/bin/lfs";
1208 snprintf(cmd, sizeof(cmd), "%s setstripe -c -1 %s", lfs, dirpath);
1210 ASSERTF(rc == 0, "system(%s): exit status %d", cmd, WEXITSTATUS(rc));
1212 layout = llapi_layout_get_by_path(dirpath, 0);
1213 ASSERTF(layout != NULL, "errno = %d\n", errno);
1215 rc = llapi_layout_stripe_count_get(layout, &count);
1216 ASSERTF(rc == 0, "errno = %d\n", errno);
1217 ASSERTF(count == LLAPI_LAYOUT_WIDE, "count = %"PRIu64"\n", count);
1219 llapi_layout_free(layout);
1222 #define T29FILE "f29"
1223 #define T29_DESC "set ost index to non-zero stripe number"
1224 static void test29(void)
1227 uint64_t ost0, ost1, nost;
1228 struct llapi_layout *layout;
1229 char path[PATH_MAX];
1234 layout = llapi_layout_alloc();
1235 ASSERTF(layout != NULL, "errno %d", errno);
1237 snprintf(path, sizeof(path), "%s/%s", lustre_dir, T29FILE);
1240 ASSERTF(rc >= 0 || errno == ENOENT, "errno = %d", errno);
1242 /* set ost index to LLAPI_LAYOUT_IDX_MAX should fail */
1243 rc = llapi_layout_ost_index_set(layout, 1, LLAPI_LAYOUT_IDX_MAX);
1244 ASSERTF(rc == -1 && errno == EINVAL, "rc = %d, errno = %d\n",
1247 /* specify ost index partially */
1248 rc = llapi_layout_ost_index_set(layout, 1, 0);
1249 ASSERTF(rc == 0, "errno = %d", errno);
1251 /* create a partially specified layout will fail */
1252 fd = llapi_layout_file_create(path, 0, 0660, layout);
1253 ASSERTF(fd == -1 && errno == EINVAL, "path = %s, fd = %d, errno = %d",
1257 ASSERTF(rc >= 0 || errno == ENOENT, "errno = %d", errno);
1259 /* specify all stripes */
1260 rc = llapi_layout_ost_index_set(layout, 0, 1);
1261 ASSERTF(rc == 0, "errno = %d", errno);
1264 fd = llapi_layout_file_create(path, 0, 0660, layout);
1265 ASSERTF(fd >= 0, "path = %s, fd = %d, errno = %d", path, fd, errno);
1268 ASSERTF(rc == 0, "errno = %d", errno);
1269 llapi_layout_free(layout);
1271 /* get layout from file */
1272 layout = llapi_layout_get_by_path(path, 0);
1273 ASSERTF(layout != NULL, "errno = %d", errno);
1275 rc = llapi_layout_ost_index_get(layout, 0, &ost0);
1276 ASSERTF(rc == 0, "errno = %d", errno);
1277 rc = llapi_layout_ost_index_get(layout, 1, &ost1);
1278 ASSERTF(rc == 0, "errno = %d", errno);
1279 ASSERTF(ost0 == 1, "%"PRIu64" != %d", ost0, 1);
1280 ASSERTF(ost1 == 0, "%"PRIu64" != %d", ost1, 0);
1281 llapi_layout_free(layout);
1283 /* specify more ost indexes to test realloc */
1285 layout = llapi_layout_alloc();
1286 ASSERTF(layout != NULL, "errno %d", errno);
1287 for (i = 0; i < LOV_MAX_STRIPE_COUNT; i++) {
1288 rc = llapi_layout_ost_index_set(layout, i, nost);
1289 ASSERTF(rc == 0, "errno = %d", errno);
1290 rc = llapi_layout_ost_index_get(layout, i, &ost0);
1291 ASSERTF(rc == 0, "errno = %d", errno);
1293 if (nost == num_osts)
1298 for (i = 0; i < LOV_MAX_STRIPE_COUNT; i++) {
1299 rc = llapi_layout_ost_index_get(layout, i, &ost0);
1300 ASSERTF(rc == 0, "errno = %d", errno);
1301 ASSERTF(ost0 == nost, "ost=%"PRIu64" nost=%"PRIu64"",
1304 if (nost == num_osts)
1307 llapi_layout_free(layout);
1310 layout = llapi_layout_alloc();
1311 ASSERTF(layout != NULL, "errno %d", errno);
1312 for (i = LOV_MAX_STRIPE_COUNT-1; i >= 0; i--) {
1313 rc = llapi_layout_ost_index_set(layout, i, nost);
1314 ASSERTF(rc == 0, "errno = %d", errno);
1315 rc = llapi_layout_ost_index_get(layout, i, &ost0);
1316 ASSERTF(rc == 0, "errno = %d", errno);
1318 if (nost == num_osts)
1323 for (i = LOV_MAX_STRIPE_COUNT-1; i <= 0; i--) {
1324 rc = llapi_layout_ost_index_get(layout, i, &ost0);
1325 ASSERTF(rc == 0, "errno = %d", errno);
1326 ASSERTF(ost0 == nost, "ost=%"PRIu64", nost=%"PRIu64"",
1329 if (nost == num_osts)
1332 llapi_layout_free(layout);
1335 #define T30FILE "f30"
1336 #define T30_DESC "create composite file, traverse components"
1337 static void test30(void)
1340 uint64_t start[3], end[3];
1342 struct llapi_layout *layout;
1343 char path[PATH_MAX];
1346 end[0] = 64 * 1024 * 1024; /* 64m */
1348 end[1] = 1 * 1024 * 1024 * 1024; /* 1G */
1350 end[2] = LUSTRE_EOF;
1355 snprintf(path, sizeof(path), "%s/%s", lustre_dir, T30FILE);
1358 ASSERTF(rc >= 0 || errno == ENOENT, "errno = %d", errno);
1360 layout = llapi_layout_alloc();
1361 ASSERTF(layout != NULL, "errno %d", errno);
1363 rc = llapi_layout_stripe_count_set(layout, 1);
1364 ASSERTF(rc == 0, "errno %d", errno);
1366 /* add component without adjusting previous component's extent
1369 rc = llapi_layout_comp_add(layout);
1370 ASSERTF(rc == -1 && errno == EINVAL, "rc %d, errno %d", rc, errno);
1372 rc = llapi_layout_comp_extent_set(layout, start[0], end[0]);
1373 ASSERTF(rc == 0, "errno %d", errno);
1375 rc = llapi_layout_comp_add(layout);
1376 ASSERTF(rc == 0, "errno %d", errno);
1378 /* set non-contiguous extent will fail */
1379 rc = llapi_layout_comp_extent_set(layout, start[1] * 2, end[1]);
1380 ASSERTF(rc == 0, "errno %d", errno);
1381 rc = llapi_layout_sanity(layout, false, false);
1382 ASSERTF(rc == 12 /*LSE_NOT_ADJACENT_PREV*/, "rc %d", rc);
1384 rc = llapi_layout_comp_extent_set(layout, start[1], end[1]);
1385 ASSERTF(rc == 0, "errno %d", errno);
1387 rc = llapi_layout_comp_add(layout);
1388 ASSERTF(rc == 0, "errno %d", errno);
1390 rc = llapi_layout_comp_extent_set(layout, start[2], end[2]);
1391 ASSERTF(rc == 0, "errno %d", errno);
1393 /* create composite file */
1394 fd = llapi_layout_file_create(path, 0, 0660, layout);
1395 ASSERTF(fd >= 0, "path = %s, fd = %d, errno = %d", path, fd, errno);
1397 llapi_layout_free(layout);
1399 /* traverse & verify all components */
1400 layout = llapi_layout_get_by_path(path, 0);
1401 ASSERTF(layout != NULL, "errno = %d", errno);
1403 /* current component should be the tail component */
1404 rc = llapi_layout_comp_extent_get(layout, &s, &e);
1405 ASSERTF(rc == 0, "errno %d", errno);
1406 ASSERTF(s == start[2] && e == end[2],
1407 "s: %"PRIu64", e: %"PRIu64"", s, e);
1409 rc = llapi_layout_comp_use(layout, LLAPI_LAYOUT_COMP_USE_FIRST);
1410 ASSERTF(rc == 0, "rc %d, errno %d", rc, errno);
1412 /* delete non-tail component will fail */
1413 rc = llapi_layout_comp_del(layout);
1414 ASSERTF(rc == -1 && errno == EINVAL, "rc %d, errno %d", rc, errno);
1416 rc = llapi_layout_comp_extent_get(layout, &s, &e);
1417 ASSERTF(rc == 0, "errno %d", errno);
1418 ASSERTF(s == start[0] && e == end[0],
1419 "s: %"PRIu64", e: %"PRIu64"", s, e);
1421 rc = llapi_layout_comp_use(layout, LLAPI_LAYOUT_COMP_USE_NEXT);
1422 ASSERTF(rc == 0, "rc %d, errno %d", rc, errno);
1424 rc = llapi_layout_comp_extent_get(layout, &s, &e);
1425 ASSERTF(rc == 0, "errno %d", errno);
1426 ASSERTF(s == start[1] && e == end[1],
1427 "s: %"PRIu64", e: %"PRIu64"", s, e);
1429 rc = llapi_layout_comp_use(layout, LLAPI_LAYOUT_COMP_USE_NEXT);
1430 ASSERTF(rc == 0, "rc %d, errno %d", rc, errno);
1432 rc = llapi_layout_comp_del(layout);
1433 ASSERTF(rc == 0, "errno %d", errno);
1435 llapi_layout_free(layout);
1438 #define T31FILE "f31"
1439 #define T31_DESC "add/delete component to/from existing file"
1440 static void test31(void)
1443 uint64_t start[2], end[2];
1446 struct llapi_layout *layout;
1447 char path[PATH_MAX];
1450 end[0] = 64 * 1024 * 1024; /* 64m */
1452 end[1] = LUSTRE_EOF;
1457 snprintf(path, sizeof(path), "%s/%s", lustre_dir, T31FILE);
1460 ASSERTF(rc >= 0 || errno == ENOENT, "errno = %d", errno);
1462 layout = llapi_layout_alloc();
1463 ASSERTF(layout != NULL, "errno %d", errno);
1465 rc = llapi_layout_stripe_count_set(layout, 1);
1466 ASSERTF(rc == 0, "errno %d", errno);
1468 rc = llapi_layout_comp_extent_set(layout, start[0], end[0]);
1469 ASSERTF(rc == 0, "errno %d", errno);
1471 /* create composite file */
1472 fd = llapi_layout_file_create(path, 0, 0660, layout);
1473 ASSERTF(fd >= 0, "path = %s, fd = %d, errno = %d", path, fd, errno);
1474 llapi_layout_free(layout);
1476 layout = llapi_layout_alloc();
1477 ASSERTF(layout != NULL, "errno %d", errno);
1479 rc = llapi_layout_stripe_count_set(layout, 2);
1480 ASSERTF(rc == 0, "errno %d", errno);
1482 rc = llapi_layout_comp_extent_set(layout, start[1], end[1]);
1483 ASSERTF(rc == 0, "errno %d", errno);
1485 /* add comopnent to existing file */
1486 rc = llapi_layout_file_comp_add(path, layout);
1487 ASSERTF(rc == 0, "errno %d", errno);
1488 llapi_layout_free(layout);
1490 /* verify the composite layout after adding */
1491 layout = llapi_layout_get_by_path(path, 0);
1492 ASSERTF(layout != NULL, "errno = %d", errno);
1494 rc = llapi_layout_comp_use(layout, LLAPI_LAYOUT_COMP_USE_FIRST);
1495 ASSERTF(rc == 0, "rc %d, errno %d", rc, errno);
1498 rc = llapi_layout_comp_extent_get(layout, &s, &e);
1499 ASSERTF(rc == 0 && i < 2, "i %d, errno %d", i, errno);
1500 ASSERTF(s == start[i] && e == end[i],
1501 "i: %d s: %"PRIu64", e: %"PRIu64"", i, s, e);
1503 rc = llapi_layout_comp_id_get(layout, &id[i]);
1504 ASSERTF(rc == 0 && id[i] != 0, "i %d, errno %d, id %d",
1507 rc = llapi_layout_comp_use(layout, LLAPI_LAYOUT_COMP_USE_NEXT);
1508 ASSERTF(rc == 0 || i == 1, "i=%d rc=%d errno=%d", i, rc, errno);
1512 /* Verify reverse iteration gives the same IDs as forward iteration */
1513 rc = llapi_layout_comp_use(layout, LLAPI_LAYOUT_COMP_USE_LAST);
1514 ASSERTF(rc == 0, "rc %d, errno %d", rc, errno);
1519 rc = llapi_layout_comp_id_get(layout, &comp_id);
1520 ASSERTF(rc == 0 && comp_id == id[i],
1521 "i %d, errno %d, id[] %u/%u", i, errno, id[i], comp_id);
1523 rc = llapi_layout_comp_use(layout, LLAPI_LAYOUT_COMP_USE_PREV);
1524 ASSERTF(rc == 0 || i == 0, "i=%d rc=%d errno=%d", i, rc, errno);
1527 llapi_layout_free(layout);
1529 /* delete non-tail component will fail */
1530 rc = llapi_layout_file_comp_del(path, id[0], 0);
1531 ASSERTF(rc < 0 && errno == EINVAL, "rc %d, errno %d", rc, errno);
1533 rc = llapi_layout_file_comp_del(path, id[1], 0);
1534 ASSERTF(rc == 0, "rc %d, errno %d", rc, errno);
1536 /* verify the composite layout after deleting */
1537 layout = llapi_layout_get_by_path(path, 0);
1538 ASSERTF(layout != NULL, "errno = %d", errno);
1540 rc = llapi_layout_comp_use(layout, LLAPI_LAYOUT_COMP_USE_FIRST);
1541 ASSERTF(rc == 0, "rc %d, errno %d", rc, errno);
1543 rc = llapi_layout_comp_extent_get(layout, &s, &e);
1544 ASSERTF(rc == 0, "errno %d", errno);
1545 ASSERTF(s == start[0] && e == end[0],
1546 "s: %"PRIu64", e: %"PRIu64"", s, e);
1549 #define T32FILE "t32"
1550 #define T32_STRIPE_COUNT (num_osts*2)
1551 #define T32_DESC "Test overstriping with layout_file_create"
1552 static void test32(void)
1557 struct llapi_layout *layout = llapi_layout_alloc();
1558 void *lmdbuf = NULL;
1559 struct lov_user_md *lmd;
1560 char path[PATH_MAX];
1562 ASSERTF(layout != NULL, "errno %d", errno);
1564 /* Maximum possible, to be on the safe side - num_osts could be large */
1565 lmdbuf = malloc(XATTR_SIZE_MAX);
1566 ASSERTF(lmdbuf != NULL, "errno %d", errno);
1569 snprintf(path, sizeof(path), "%s/%s", lustre_dir, T32FILE);
1572 ASSERTF(rc >= 0 || errno == ENOENT, "errno = %d", errno);
1575 rc = llapi_layout_stripe_count_set(layout, T32_STRIPE_COUNT);
1576 ASSERTF(rc == 0, "errno = %d", errno);
1577 rc = llapi_layout_stripe_count_get(layout, &count);
1578 ASSERTF(rc == 0 && count == T32_STRIPE_COUNT, "%"PRIu64" != %d", count,
1581 rc = llapi_layout_pattern_set(layout, LLAPI_LAYOUT_OVERSTRIPING);
1582 ASSERTF(rc == 0, "errno = %d", errno);
1585 fd = llapi_layout_file_create(path, 0, 0660, layout);
1586 ASSERTF(fd >= 0, "path = %s, errno = %d", path, errno);
1588 rc = ioctl(fd, LL_IOC_LOV_GETSTRIPE_NEW, lmdbuf);
1589 ASSERTF(rc == 0, "errno = %d", errno);
1591 count = lmd->lmm_stripe_count;
1592 ASSERTF(count == T32_STRIPE_COUNT,
1593 "stripe count (%"PRIu64") not equal to expected (%d)",
1594 count, T32_STRIPE_COUNT);
1597 ASSERTF(rc == 0, "errno = %d", errno);
1598 llapi_layout_free(layout);
1602 #define T33FILE "t33"
1603 #define T33_STRIPE_COUNT (num_osts*2)
1604 #define T33_DESC "Test overstriping with llapi_file_open"
1605 static void test33(void)
1610 void *lmdbuf = NULL;
1611 struct lov_user_md *lmd;
1612 char path[PATH_MAX];
1614 /* Maximum possible, to be on the safe side - num_osts could be large */
1615 lmdbuf = malloc(XATTR_SIZE_MAX);
1616 ASSERTF(lmdbuf != NULL, "errno %d", errno);
1619 snprintf(path, sizeof(path), "%s/%s", lustre_dir, T33FILE);
1622 ASSERTF(rc >= 0 || errno == ENOENT, "errno = %d", errno);
1624 fd = llapi_file_open(path, O_CREAT | O_RDWR, 0660, 0, -1, num_osts*2,
1625 LOV_PATTERN_RAID0 | LOV_PATTERN_OVERSTRIPING);
1626 ASSERTF(fd >= 0, "path = %s, errno = %d", path, errno);
1628 rc = ioctl(fd, LL_IOC_LOV_GETSTRIPE_NEW, lmdbuf);
1629 ASSERTF(rc == 0, "errno = %d", errno);
1631 count = lmd->lmm_stripe_count;
1632 ASSERTF(count == T33_STRIPE_COUNT,
1633 "stripe count (%"PRIu64") not equal to expected (%d)",
1634 count, T33_STRIPE_COUNT);
1637 ASSERTF(rc == 0, "errno = %d", errno);
1641 #define T34FILE "f34"
1642 #define T34_DESC "create simple valid & invalid self extending layouts"
1643 static void test34(void)
1646 uint64_t start[4], end[4];
1647 struct llapi_layout *layout;
1648 char path[PATH_MAX];
1651 end[0] = 10 * 1024 * 1024; /* 10m */
1653 end[1] = 1024 * 1024 * 1024; /* 1G */
1655 end[2] = 10ull * 1024 * 1024 * 1024; /* 10G */
1657 end[3] = LUSTRE_EOF;
1662 snprintf(path, sizeof(path), "%s/%s", lustre_dir, T34FILE);
1665 ASSERTF(rc >= 0 || errno == ENOENT, "errno = %d", errno);
1667 layout = llapi_layout_alloc();
1668 ASSERTF(layout != NULL, "errno %d", errno);
1670 rc = llapi_layout_stripe_count_set(layout, 1);
1671 ASSERTF(rc == 0, "errno %d", errno);
1673 /* add component without adjusting previous component's extent
1676 rc = llapi_layout_comp_add(layout);
1677 ASSERTF(rc == -1 && errno == EINVAL, "rc %d, errno %d", rc, errno);
1679 rc = llapi_layout_comp_extent_set(layout, start[0], end[0]);
1680 ASSERTF(rc == 0, "errno %d", errno);
1682 rc = llapi_layout_comp_add(layout);
1683 ASSERTF(rc == 0, "errno %d", errno);
1685 rc = llapi_layout_comp_extent_set(layout, start[1], end[1]);
1686 ASSERTF(rc == 0, "errno %d", errno);
1688 rc = llapi_layout_comp_flags_set(layout, LCME_FL_EXTENSION);
1689 ASSERTF(rc == 0, "errno %d", errno);
1691 /* Invalid size, too small - < 64 MiB */
1692 rc = llapi_layout_extension_size_set(layout, 32 << 20);
1693 ASSERTF(rc == -1, "errno %d", errno);
1695 /* too large - > 4 TiB */
1696 rc = llapi_layout_extension_size_set(layout, 5ull << 40);
1697 ASSERTF(rc == -1, "errno %d", errno);
1699 /* Valid size, 64 MiB */
1700 rc = llapi_layout_extension_size_set(layout, 64 << 20);
1701 ASSERTF(rc == 0, "errno %d", errno);
1703 rc = llapi_layout_comp_add(layout);
1704 ASSERTF(rc == 0, "errno %d", errno);
1706 rc = llapi_layout_comp_extent_set(layout, start[2], end[2]);
1707 ASSERTF(rc == 0, "errno %d", errno);
1709 /* Set extension space flag on adjacent components:
1710 * This is invalid, but can't be checked until we create the file.
1712 rc = llapi_layout_comp_flags_set(layout, LCME_FL_EXTENSION);
1713 ASSERTF(rc == 0, "errno %d", errno);
1715 fd = llapi_layout_file_create(path, 0, 0660, layout);
1716 ASSERTF(fd = -1, "path = %s, fd = %d, errno = %d", path, fd, errno);
1718 /* Delete incorrect component */
1719 rc = llapi_layout_comp_del(layout);
1720 ASSERTF(rc == 0, "errno %d", errno);
1722 rc = llapi_layout_comp_add(layout);
1723 ASSERTF(rc == 0, "errno %d", errno);
1725 /* Convert this comp to 0-len that can be followed by extension space */
1726 rc = llapi_layout_comp_extent_set(layout, start[2], start[2]);
1727 ASSERTF(rc == 0, "errno %d", errno);
1729 rc = llapi_layout_comp_add(layout);
1730 ASSERTF(rc == 0, "errno %d", errno);
1732 rc = llapi_layout_comp_extent_set(layout, start[2], end[3]);
1733 ASSERTF(rc == 0, "errno %d", errno);
1735 rc = llapi_layout_comp_flags_set(layout, LCME_FL_EXTENSION);
1736 ASSERTF(rc == 0, "errno %d", errno);
1738 /* create composite file */
1739 fd = llapi_layout_file_create(path, 0, 0660, layout);
1740 ASSERTF(fd >= 0, "path = %s, fd = %d, errno = %d", path, fd, errno);
1742 llapi_layout_free(layout);
1744 /* traverse & verify all components */
1745 layout = llapi_layout_get_by_path(path, 0);
1746 ASSERTF(layout != NULL, "errno = %d", errno);
1748 rc = llapi_layout_sanity(layout, false, false);
1749 ASSERTF(rc == 0, "errno %d", errno);
1752 #define TEST_DESC_LEN 80
1753 struct test_tbl_entry {
1754 void (*tte_fn)(void);
1755 char tte_desc[TEST_DESC_LEN];
1759 static struct test_tbl_entry test_tbl[] = {
1760 { .tte_fn = &test0, .tte_desc = T0_DESC, .tte_skip = false },
1761 { .tte_fn = &test1, .tte_desc = T1_DESC, .tte_skip = false },
1762 { .tte_fn = &test2, .tte_desc = T2_DESC, .tte_skip = false },
1763 { .tte_fn = &test3, .tte_desc = T3_DESC, .tte_skip = false },
1764 { .tte_fn = &test4, .tte_desc = T4_DESC, .tte_skip = false },
1765 { .tte_fn = &test5, .tte_desc = T5_DESC, .tte_skip = false },
1766 { .tte_fn = &test6, .tte_desc = T6_DESC, .tte_skip = false },
1767 { .tte_fn = &test7, .tte_desc = T7_DESC, .tte_skip = false },
1768 { .tte_fn = &test8, .tte_desc = T8_DESC, .tte_skip = false },
1769 { .tte_fn = &test9, .tte_desc = T9_DESC, .tte_skip = false },
1770 { .tte_fn = &test10, .tte_desc = T10_DESC, .tte_skip = false },
1771 { .tte_fn = &test11, .tte_desc = T11_DESC, .tte_skip = false },
1772 { .tte_fn = &test12, .tte_desc = T12_DESC, .tte_skip = false },
1773 { .tte_fn = &test13, .tte_desc = T13_DESC, .tte_skip = false },
1774 { .tte_fn = &test14, .tte_desc = T14_DESC, .tte_skip = false },
1775 { .tte_fn = &test15, .tte_desc = T15_DESC, .tte_skip = false },
1776 { .tte_fn = &test16, .tte_desc = T16_DESC, .tte_skip = false },
1777 { .tte_fn = &test17, .tte_desc = T17_DESC, .tte_skip = false },
1778 { .tte_fn = &test18, .tte_desc = T18_DESC, .tte_skip = false },
1779 { .tte_fn = &test19, .tte_desc = T19_DESC, .tte_skip = false },
1780 { .tte_fn = &test20, .tte_desc = T20_DESC, .tte_skip = false },
1781 { .tte_fn = &test21, .tte_desc = T21_DESC, .tte_skip = false },
1782 { .tte_fn = &test22, .tte_desc = T22_DESC, .tte_skip = false },
1783 { .tte_fn = &test23, .tte_desc = T23_DESC, .tte_skip = false },
1784 { .tte_fn = &test24, .tte_desc = T24_DESC, .tte_skip = false },
1785 { .tte_fn = &test25, .tte_desc = T25_DESC, .tte_skip = false },
1786 { .tte_fn = &test26, .tte_desc = T26_DESC, .tte_skip = false },
1787 { .tte_fn = &test27, .tte_desc = T27_DESC, .tte_skip = false },
1788 { .tte_fn = &test28, .tte_desc = T28_DESC, .tte_skip = false },
1789 { .tte_fn = &test29, .tte_desc = T29_DESC, .tte_skip = false },
1790 { .tte_fn = &test30, .tte_desc = T30_DESC, .tte_skip = false },
1791 { .tte_fn = &test31, .tte_desc = T31_DESC, .tte_skip = false },
1792 { .tte_fn = &test32, .tte_desc = T32_DESC, .tte_skip = false },
1793 { .tte_fn = &test33, .tte_desc = T33_DESC, .tte_skip = false },
1794 { .tte_fn = &test34, .tte_desc = T34_DESC, .tte_skip = false },
1797 #define NUM_TESTS (sizeof(test_tbl) / sizeof(struct test_tbl_entry))
1799 static void print_test_desc(int test_num, const char *test_desc,
1804 printf(" test %2d: %s ", test_num, test_desc);
1805 for (i = 0; i < TEST_DESC_LEN - strlen(test_desc); i++)
1807 printf(" %s\n", status);
1810 /* This function runs a single test by forking the process. This way,
1811 * if there is a segfault during a test, the test program won't crash.
1813 static int test(void (*test_fn)(), const char *test_desc, bool test_skip,
1818 char status_buf[128];
1821 if (!run_list_provided)
1822 print_test_desc(test_num, test_desc, "skip");
1828 ERROR("cannot fork: %s", strerror(errno));
1829 } else if (pid > 0) {
1832 /* Non-zero value indicates failure. */
1835 strncpy(status_buf, "pass", sizeof(status_buf));
1836 } else if WIFSIGNALED(status) {
1837 snprintf(status_buf, sizeof(status_buf),
1838 "fail (exit status %d, killed by SIG%d)",
1839 WEXITSTATUS(status), WTERMSIG(status));
1842 snprintf(status_buf, sizeof(status_buf),
1843 "fail (exit status %d)", WEXITSTATUS(status));
1846 print_test_desc(test_num, test_desc, status_buf);
1847 } else if (pid == 0) {
1848 /* Run the test in the child process. Exit with 0 for success,
1849 * non-zero for failure
1858 /* 'str_tests' are the tests to be skipped, such as "1,3,4,.." */
1859 static void set_tests_skipped(char *str_tests)
1861 char *ptr = str_tests;
1864 if (ptr == NULL || strlen(ptr) == 0)
1867 while (*ptr != '\0') {
1868 tstno = strtoul(ptr, &ptr, 0);
1869 if (tstno >= 0 && tstno < NUM_TESTS)
1870 test_tbl[tstno].tte_skip = true;
1878 static void set_tests_to_run(char *str_tests)
1880 char *ptr = str_tests;
1884 if (ptr == NULL || strlen(ptr) == 0)
1887 for (i = 0; i < NUM_TESTS ; i++)
1888 test_tbl[i].tte_skip = true;
1890 while (*ptr != '\0') {
1891 tstno = strtoul(ptr, &ptr, 0);
1892 if (tstno >= 0 && tstno < NUM_TESTS)
1893 test_tbl[tstno].tte_skip = false;
1901 static void process_args(int argc, char *argv[])
1905 while ((c = getopt(argc, argv, "d:p:o:s:t:")) != -1) {
1908 lustre_dir = optarg;
1914 num_osts = atoi(optarg);
1917 set_tests_skipped(optarg);
1920 run_list_provided = true;
1921 set_tests_to_run(optarg);
1924 fprintf(stderr, "Unknown option '%c'\n", optopt);
1930 int main(int argc, char *argv[])
1937 llapi_msg_set_level(LLAPI_MSG_OFF);
1939 process_args(argc, argv);
1940 if (lustre_dir == NULL)
1941 lustre_dir = "/mnt/lustre";
1942 if (poolname == NULL)
1943 poolname = "testpool";
1948 DIE("Error: at least 2 OSTS are required\n");
1950 if (stat(lustre_dir, &s) < 0)
1951 DIE("cannot stat %s: %s\n", lustre_dir, strerror(errno));
1952 else if (!S_ISDIR(s.st_mode))
1953 DIE("%s: not a directory\n", lustre_dir);
1955 rc = llapi_search_fsname(lustre_dir, fsname);
1957 fprintf(stderr, "Error: %s: not a Lustre filesystem\n",
1962 /* Play nice with Lustre test scripts. Non-line buffered output
1963 * stream under I/O redirection may appear incorrectly.
1965 setvbuf(stdout, NULL, _IOLBF, 0);
1967 for (i = 0; i < NUM_TESTS; i++) {
1968 struct test_tbl_entry *tst = &test_tbl[i];
1970 if (test(tst->tte_fn, tst->tte_desc, tst->tte_skip, i) != 0)