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 int num_osts = -1;
75 void usage(char *prog)
77 printf("Usage: %s [-d lustre_dir] [-p pool_name] [-o num_osts] "
78 "[-s $n,$m,..]\n", prog);
83 #define T0_STRIPE_COUNT num_osts
84 #define T0_STRIPE_SIZE 1048576
85 #define T0_OST_OFFSET (num_osts - 1)
86 #define T0_DESC "Read/write layout attributes then create a file"
93 struct llapi_layout *layout = llapi_layout_alloc();
95 char mypool[LOV_MAXPOOLNAME + 1] = { '\0' };
97 ASSERTF(layout != NULL, "errno %d", errno);
99 snprintf(path, sizeof(path), "%s/%s", lustre_dir, T0FILE);
102 ASSERTF(rc >= 0 || errno == ENOENT, "errno = %d", errno);
105 rc = llapi_layout_stripe_count_set(layout, T0_STRIPE_COUNT);
106 ASSERTF(rc == 0, "errno = %d", errno);
107 rc = llapi_layout_stripe_count_get(layout, &count);
108 ASSERTF(rc == 0 && count == T0_STRIPE_COUNT, "%"PRIu64" != %d", count,
112 rc = llapi_layout_stripe_size_set(layout, T0_STRIPE_SIZE);
113 ASSERTF(rc == 0, "errno = %d", errno);
114 rc = llapi_layout_stripe_size_get(layout, &size);
115 ASSERTF(rc == 0 && size == T0_STRIPE_SIZE, "%"PRIu64" != %d", size,
119 rc = llapi_layout_pool_name_set(layout, poolname);
120 ASSERTF(rc == 0, "errno = %d", errno);
121 rc = llapi_layout_pool_name_get(layout, mypool, sizeof(mypool));
122 ASSERTF(rc == 0, "errno = %d", errno);
123 rc = strcmp(mypool, poolname);
124 ASSERTF(rc == 0, "%s != %s", mypool, poolname);
127 rc = llapi_layout_ost_index_set(layout, 0, T0_OST_OFFSET);
128 ASSERTF(rc == 0, "errno = %d", errno);
131 fd = llapi_layout_file_create(path, 0, 0660, layout);
132 ASSERTF(fd >= 0, "path = %s, errno = %d", path, errno);
134 ASSERTF(rc == 0, "errno = %d", errno);
135 llapi_layout_free(layout);
138 void __test1_helper(struct llapi_layout *layout)
145 char mypool[LOV_MAXPOOLNAME + 1] = { '\0' };
147 rc = llapi_layout_stripe_count_get(layout, &count);
148 ASSERTF(count == T0_STRIPE_COUNT, "%"PRIu64" != %d", count,
151 rc = llapi_layout_stripe_size_get(layout, &size);
152 ASSERTF(size == T0_STRIPE_SIZE, "%"PRIu64" != %d", size,
155 rc = llapi_layout_pool_name_get(layout, mypool, sizeof(mypool));
156 ASSERTF(rc == 0, "errno = %d", errno);
157 rc = strcmp(mypool, poolname);
158 ASSERTF(rc == 0, "%s != %s", mypool, poolname);
160 rc = llapi_layout_ost_index_get(layout, 0, &ost0);
161 ASSERTF(rc == 0, "errno = %d", errno);
162 rc = llapi_layout_ost_index_get(layout, 1, &ost1);
163 ASSERTF(rc == 0, "errno = %d", errno);
164 ASSERTF(ost0 == T0_OST_OFFSET, "%"PRIu64" != %d", ost0, T0_OST_OFFSET);
165 ASSERTF(ost1 != ost0, "%"PRIu64" == %"PRIu64, ost0, ost1);
168 #define T1_DESC "Read test0 file by path and verify attributes"
173 snprintf(path, sizeof(path), "%s/%s", lustre_dir, T0FILE);
174 struct llapi_layout *layout = llapi_layout_get_by_path(path, 0);
175 ASSERTF(layout != NULL, "errno = %d", errno);
176 __test1_helper(layout);
177 llapi_layout_free(layout);
180 #define T2_DESC "Read test0 file by FD and verify attributes"
187 snprintf(path, sizeof(path), "%s/%s", lustre_dir, T0FILE);
189 fd = open(path, O_RDONLY);
190 ASSERTF(fd >= 0, "open(%s): errno = %d", path, errno);
192 struct llapi_layout *layout = llapi_layout_get_by_fd(fd, 0);
193 ASSERTF(layout != NULL, "errno = %d", errno);
196 ASSERTF(rc == 0, "close(%s): errno = %d", path, errno);
198 __test1_helper(layout);
199 llapi_layout_free(layout);
202 #define T3_DESC "Read test0 file by FID and verify attributes"
206 struct llapi_layout *layout;
211 snprintf(path, sizeof(path), "%s/%s", lustre_dir, T0FILE);
213 rc = llapi_path2fid(path, &fid);
214 ASSERTF(rc == 0, "rc = %d, errno = %d", rc, errno);
215 snprintf(fidstr, sizeof(fidstr), "0x%"PRIx64":0x%x:0x%x",
216 (uint64_t)fid.f_seq, fid.f_oid, fid.f_ver);
218 layout = llapi_layout_get_by_fid(path, &fid, 0);
219 ASSERTF(layout != NULL, "fidstr = %s, errno = %d", fidstr, errno);
221 __test1_helper(layout);
222 llapi_layout_free(layout);
226 #define T4_STRIPE_COUNT 2
227 #define T4_STRIPE_SIZE 2097152
228 #define T4_DESC "Verify compatibility with 'lfs setstripe'"
236 const char *lfs = getenv("LFS");
237 char mypool[LOV_MAXPOOLNAME + 1] = { '\0' };
238 char cmd[PATH_MAX + 128];
241 snprintf(path, sizeof(path), "%s/%s", lustre_dir, T4FILE);
244 lfs = "/usr/bin/lfs";
247 ASSERTF(rc == 0 || errno == ENOENT, "errno = %d", errno);
249 snprintf(cmd, sizeof(cmd), "%s setstripe %s %s -c %d -S %d %s", lfs,
250 strlen(poolname) > 0 ? "-p" : "", poolname, T4_STRIPE_COUNT,
251 T4_STRIPE_SIZE, path);
253 ASSERTF(rc == 0, "system(%s): exit status %d", cmd, WEXITSTATUS(rc));
256 struct llapi_layout *layout = llapi_layout_get_by_path(path, 0);
257 ASSERTF(layout != NULL, "errno = %d", errno);
259 rc = llapi_layout_stripe_count_get(layout, &count);
260 ASSERTF(count == T4_STRIPE_COUNT, "%"PRIu64" != %d", count,
263 rc = llapi_layout_stripe_size_get(layout, &size);
264 ASSERTF(size == T4_STRIPE_SIZE, "%"PRIu64" != %d", size,
267 rc = llapi_layout_pool_name_get(layout, mypool, sizeof(mypool));
268 ASSERTF(rc == 0, "errno = %d", errno);
269 rc = strcmp(mypool, poolname);
270 ASSERTF(rc == 0, "%s != %s", mypool, poolname);
272 rc = llapi_layout_ost_index_get(layout, 0, &ost0);
273 ASSERTF(rc == 0, "errno = %d", errno);
274 rc = llapi_layout_ost_index_get(layout, 1, &ost1);
275 ASSERTF(rc == 0, "errno = %d", errno);
276 ASSERTF(ost1 != ost0, "%"PRIu64" == %"PRIu64, ost0, ost1);
278 llapi_layout_free(layout);
282 #define T5_DESC "llapi_layout_get_by_path ENOENT handling"
287 struct llapi_layout *layout;
289 snprintf(path, sizeof(path), "%s/%s", lustre_dir, T5FILE);
292 ASSERTF(rc == 0 || errno == ENOENT, "errno = %d", errno);
295 layout = llapi_layout_get_by_path(path, 0);
296 ASSERTF(layout == NULL && errno == ENOENT, "errno = %d", errno);
299 #define T6_DESC "llapi_layout_get_by_fd EBADF handling"
303 struct llapi_layout *layout = llapi_layout_get_by_fd(9999, 0);
304 ASSERTF(layout == NULL && errno == EBADF, "errno = %d", errno);
308 #define T7_DESC "llapi_layout_get_by_path EACCES handling"
313 uid_t myuid = getuid();
315 const char *runas = getenv("RUNAS_ID");
319 snprintf(path, sizeof(path), "%s/%s", lustre_dir, T7FILE);
320 ASSERTF(myuid == 0, "myuid = %d", myuid); /* Need root for this test. */
322 /* Create file as root */
324 ASSERTF(rc == 0 || errno == ENOENT, "errno = %d", errno);
326 fd = open(path, O_CREAT, 0400);
327 ASSERTF(fd > 0, "errno = %d", errno);
329 ASSERTF(rc == 0, "errno = %d", errno);
331 /* Become unprivileged user */
334 ASSERTF(uid != 0, "runas = %s", runas);
336 pw = getpwnam("nobody");
337 ASSERTF(pw != NULL, "errno = %d", errno);
341 ASSERTF(rc == 0, "errno = %d", errno);
343 struct llapi_layout *layout = llapi_layout_get_by_path(path, 0);
344 ASSERTF(layout == NULL && errno == EACCES, "errno = %d", errno);
346 ASSERTF(rc == 0, "errno = %d", errno);
349 /* llapi_layout_get_by_path() returns default layout for file with no
350 * striping attributes. */
352 #define T8_DESC "llapi_layout_get_by_path ENODATA handling"
357 struct llapi_layout *layout;
363 snprintf(path, sizeof(path), "%s/%s", lustre_dir, T8FILE);
366 ASSERTF(rc >= 0 || errno == ENOENT, "errno = %d", errno);
367 fd = open(path, O_CREAT, 0640);
368 ASSERTF(fd >= 0, "errno = %d", errno);
370 ASSERTF(rc == 0, "errno = %d", errno);
372 layout = llapi_layout_get_by_path(path, 0);
373 ASSERTF(layout != NULL, "errno = %d\n", errno);
375 rc = llapi_layout_stripe_count_get(layout, &count);
376 ASSERTF(rc == 0, "errno = %d\n", errno);
377 ASSERTF(count == LLAPI_LAYOUT_DEFAULT, "count = %"PRIu64"\n", count);
379 rc = llapi_layout_stripe_size_get(layout, &size);
380 ASSERTF(rc == 0, "errno = %d\n", errno);
381 ASSERTF(size == LLAPI_LAYOUT_DEFAULT, "size = %"PRIu64"\n", size);
383 rc = llapi_layout_pattern_get(layout, &pattern);
384 ASSERTF(rc == 0, "errno = %d\n", errno);
385 ASSERTF(pattern == LLAPI_LAYOUT_DEFAULT, "pattern = %"PRIu64"\n",
388 llapi_layout_free(layout);
391 /* Verify llapi_layout_patter_set() return values for various inputs. */
392 #define T9_DESC "verify llapi_layout_pattern_set() return values"
395 struct llapi_layout *layout;
398 layout = llapi_layout_alloc();
399 ASSERTF(layout != NULL, "errno = %d\n", errno);
402 rc = llapi_layout_pattern_set(layout, LLAPI_LAYOUT_INVALID);
403 ASSERTF(rc == -1 && errno == EOPNOTSUPP, "rc = %d, errno = %d", rc,
407 rc = llapi_layout_pattern_set(NULL, LLAPI_LAYOUT_DEFAULT);
408 ASSERTF(rc == -1 && errno == EINVAL, "rc = %d, errno = %d", rc,
412 rc = llapi_layout_pattern_set(layout, LLAPI_LAYOUT_DEFAULT);
413 ASSERTF(rc == 0, "rc = %d, errno = %d", rc, errno);
416 rc = llapi_layout_pattern_set(layout, LLAPI_LAYOUT_RAID0);
417 ASSERTF(rc == 0, "rc = %d, errno = %d", rc, errno);
419 llapi_layout_free(layout);
422 /* Verify stripe_count interfaces return errors as expected */
423 #define T10_DESC "stripe_count error handling"
428 struct llapi_layout *layout;
430 layout = llapi_layout_alloc();
431 ASSERTF(layout != NULL, "errno = %d", errno);
433 /* invalid stripe count */
435 rc = llapi_layout_stripe_count_set(layout, LLAPI_LAYOUT_INVALID);
436 ASSERTF(rc == -1 && errno == EINVAL, "rc = %d, errno = %d", rc, errno);
439 rc = llapi_layout_stripe_count_set(layout, -1);
440 ASSERTF(rc == -1 && errno == EINVAL, "rc = %d, errno = %d", rc, errno);
444 rc = llapi_layout_stripe_count_set(NULL, 2);
445 ASSERTF(rc == -1 && errno == EINVAL, "rc = %d, errno = %d", rc, errno);
449 rc = llapi_layout_stripe_count_get(NULL, &count);
450 ASSERTF(rc == -1 && errno == EINVAL, "rc = %d, errno = %d", rc, errno);
454 rc = llapi_layout_stripe_count_get(layout, NULL);
455 ASSERTF(rc == -1 && errno == EINVAL, "rc = %d, errno = %d", rc, errno);
457 /* stripe count too large */
459 rc = llapi_layout_stripe_count_set(layout, LOV_MAX_STRIPE_COUNT + 1);
460 ASSERTF(rc == -1 && errno == EINVAL, "rc = %d, errno = %d", rc, errno);
461 llapi_layout_free(layout);
464 /* Verify stripe_size interfaces return errors as expected */
465 #define T11_DESC "stripe_size error handling"
470 struct llapi_layout *layout;
472 layout = llapi_layout_alloc();
473 ASSERTF(layout != NULL, "errno = %d", errno);
475 /* negative stripe size */
477 rc = llapi_layout_stripe_size_set(layout, -1);
478 ASSERTF(rc == -1 && errno == EINVAL, "rc = %d, errno = %d", rc, errno);
480 /* invalid stripe size */
482 rc = llapi_layout_stripe_size_set(layout, LLAPI_LAYOUT_INVALID);
483 ASSERTF(rc == -1 && errno == EINVAL, "rc = %d, errno = %d", rc, errno);
485 /* stripe size too big */
487 rc = llapi_layout_stripe_size_set(layout, (1ULL << 33));
488 ASSERTF(rc == -1 && errno == EINVAL, "rc = %d, errno = %d", rc, errno);
492 rc = llapi_layout_stripe_size_set(NULL, 1048576);
493 ASSERTF(rc == -1 && errno == EINVAL, "rc = %d, errno = %d", rc, errno);
496 rc = llapi_layout_stripe_size_get(NULL, &size);
497 ASSERTF(rc == -1 && errno == EINVAL, "rc = %d, errno = %d", rc, errno);
501 rc = llapi_layout_stripe_size_get(layout, NULL);
502 ASSERTF(rc == -1 && errno == EINVAL, "rc = %d, errno = %d", rc, errno);
504 llapi_layout_free(layout);
507 /* Verify pool_name interfaces return errors as expected */
508 #define T12_DESC "pool_name error handling"
512 struct llapi_layout *layout;
513 char mypool[LOV_MAXPOOLNAME + 1] = { '\0' };
515 layout = llapi_layout_alloc();
516 ASSERTF(layout != NULL, "errno = %d", errno);
520 rc = llapi_layout_pool_name_set(NULL, "foo");
521 ASSERTF(rc == -1 && errno == EINVAL, "rc = %d, errno = %d", rc, errno);
525 rc = llapi_layout_pool_name_set(layout, NULL);
526 ASSERTF(rc == -1 && errno == EINVAL, "rc = %d, errno = %d", rc, errno);
530 rc = llapi_layout_pool_name_get(NULL, mypool, sizeof(mypool));
531 ASSERTF(errno == EINVAL, "poolname = %s, errno = %d", poolname, errno);
535 rc = llapi_layout_pool_name_get(layout, NULL, sizeof(mypool));
536 ASSERTF(errno == EINVAL, "poolname = %s, errno = %d", poolname, errno);
538 /* Pool name too long*/
540 rc = llapi_layout_pool_name_set(layout, "0123456789abcdef");
541 ASSERTF(rc == -1 && errno == EINVAL, "rc = %d, errno = %d", rc, errno);
543 llapi_layout_free(layout);
546 /* Verify ost_index interface returns errors as expected */
547 #define T13FILE "t13"
548 #define T13_STRIPE_COUNT 2
549 #define T13_DESC "ost_index error handling"
555 struct llapi_layout *layout;
558 snprintf(path, sizeof(path), "%s/%s", lustre_dir, T13FILE);
560 layout = llapi_layout_alloc();
561 ASSERTF(layout != NULL, "errno = %d", errno);
563 /* invalid OST index */
565 rc = llapi_layout_ost_index_set(layout, 0, LLAPI_LAYOUT_INVALID);
566 ASSERTF(rc == -1 && errno == EINVAL, "rc = %d, errno = %d", rc, errno);
569 rc = llapi_layout_ost_index_set(layout, 0, -1);
570 ASSERTF(rc == -1 && errno == EINVAL, "rc = %d, errno = %d", rc, errno);
574 rc = llapi_layout_ost_index_set(NULL, 0, 1);
575 ASSERTF(rc == -1 && errno == EINVAL, "rc = %d, errno = %d", rc, errno);
578 rc = llapi_layout_ost_index_get(NULL, 0, &idx);
579 ASSERTF(rc == -1 && errno == EINVAL, "rc = %d, errno = %d", rc, errno);
583 rc = llapi_layout_ost_index_get(layout, 0, NULL);
584 ASSERTF(rc == -1 && errno == EINVAL, "rc = %d, errno = %d", rc, errno);
586 /* Layout not read from file so has no OST data. */
588 rc = llapi_layout_stripe_count_set(layout, T13_STRIPE_COUNT);
589 ASSERTF(rc == 0, "errno = %d", errno);
590 rc = llapi_layout_ost_index_get(layout, 0, &idx);
591 ASSERTF(rc == -1 && errno == EINVAL, "rc = %d, errno = %d", rc, errno);
593 /* n greater than stripe count*/
595 ASSERTF(rc >= 0 || errno == ENOENT, "errno = %d", errno);
596 rc = llapi_layout_stripe_count_set(layout, T13_STRIPE_COUNT);
597 ASSERTF(rc == 0, "errno = %d", errno);
598 fd = llapi_layout_file_create(path, 0, 0644, layout);
599 ASSERTF(fd >= 0, "errno = %d", errno);
601 ASSERTF(rc == 0, "errno = %d", errno);
602 llapi_layout_free(layout);
604 layout = llapi_layout_get_by_path(path, 0);
605 ASSERTF(layout != NULL, "errno = %d", errno);
607 rc = llapi_layout_ost_index_get(layout, T13_STRIPE_COUNT + 1, &idx);
608 ASSERTF(rc == -1 && errno == EINVAL, "rc = %d, errno = %d", rc, errno);
610 llapi_layout_free(layout);
613 /* Verify llapi_layout_file_create() returns errors as expected */
614 #define T14_DESC "llapi_layout_file_create error handling"
618 struct llapi_layout *layout = llapi_layout_alloc();
622 rc = llapi_layout_file_create(NULL, 0, 0, layout);
623 ASSERTF(rc == -1 && errno == EINVAL, "rc = %d, errno = %d", rc, errno);
625 llapi_layout_free(layout);
628 /* Can't change striping attributes of existing file. */
629 #define T15FILE "t15"
630 #define T15_STRIPE_COUNT 2
631 #define T15_DESC "Can't change striping attributes of existing file"
637 struct llapi_layout *layout;
640 snprintf(path, sizeof(path), "%s/%s", lustre_dir, T15FILE);
643 ASSERTF(rc >= 0 || errno == ENOENT, "errno = %d", errno);
645 layout = llapi_layout_alloc();
646 ASSERTF(layout != NULL, "errno = %d", errno);
647 rc = llapi_layout_stripe_count_set(layout, T15_STRIPE_COUNT);
648 ASSERTF(rc == 0, "errno = %d", errno);
651 fd = llapi_layout_file_create(path, 0, 0640, layout);
652 ASSERTF(fd >= 0, "fd = %d, errno = %d", fd, errno);
654 ASSERTF(rc == 0, "errno = %d", errno);
656 rc = llapi_layout_stripe_count_set(layout, T15_STRIPE_COUNT - 1);
658 fd = llapi_layout_file_open(path, 0, 0640, layout);
659 ASSERTF(fd >= 0, "fd = %d, errno = %d", fd, errno);
661 ASSERTF(rc == 0, "errno = %d", errno);
662 llapi_layout_free(layout);
664 layout = llapi_layout_get_by_path(path, 0);
665 ASSERTF(layout != NULL, "errno = %d", errno);
666 rc = llapi_layout_stripe_count_get(layout, &count);
667 ASSERTF(rc == 0 && count == T15_STRIPE_COUNT,
668 "rc = %d, %"PRIu64" != %d", rc, count, T15_STRIPE_COUNT);
669 llapi_layout_free(layout);
672 /* Default stripe attributes are applied as expected. */
673 #define T16FILE "t16"
674 #define T16_DESC "Default stripe attributes are applied as expected"
679 struct llapi_layout *deflayout;
680 struct llapi_layout *filelayout;
687 snprintf(path, sizeof(path), "%s/%s", lustre_dir, T16FILE);
690 ASSERTF(rc == 0 || errno == ENOENT, "errno = %d", errno);
692 deflayout = llapi_layout_get_by_path(lustre_dir, LAYOUT_GET_EXPECTED);
693 ASSERTF(deflayout != NULL, "errno = %d", errno);
694 rc = llapi_layout_stripe_size_get(deflayout, &dsize);
695 ASSERTF(rc == 0, "errno = %d", errno);
696 rc = llapi_layout_stripe_count_get(deflayout, &dcount);
697 ASSERTF(rc == 0, "errno = %d", errno);
699 /* First, with a default struct llapi_layout */
700 filelayout = llapi_layout_alloc();
701 ASSERTF(filelayout != NULL, "errno = %d", errno);
703 fd = llapi_layout_file_create(path, 0, 0640, filelayout);
704 ASSERTF(fd >= 0, "errno = %d", errno);
707 ASSERTF(rc == 0, "errno = %d", errno);
709 llapi_layout_free(filelayout);
711 filelayout = llapi_layout_get_by_path(path, 0);
712 ASSERTF(filelayout != NULL, "errno = %d", errno);
714 rc = llapi_layout_stripe_count_get(filelayout, &fcount);
715 ASSERTF(rc == 0, "errno = %d", errno);
716 ASSERTF(fcount == dcount || dcount == LLAPI_LAYOUT_DEFAULT ||
717 dcount == LLAPI_LAYOUT_WIDE,
718 "%"PRIu64" != %"PRIu64, fcount, dcount);
720 rc = llapi_layout_stripe_size_get(filelayout, &fsize);
721 ASSERTF(rc == 0, "errno = %d", errno);
722 ASSERTF(fsize == dsize, "%"PRIu64" != %"PRIu64, fsize, dsize);
724 /* NULL layout also implies default layout */
726 ASSERTF(rc == 0 || errno == ENOENT, "errno = %d", errno);
728 fd = llapi_layout_file_create(path, 0, 0640, filelayout);
729 ASSERTF(fd >= 0, "errno = %d", errno);
731 ASSERTF(rc == 0, "errno = %d", errno);
732 filelayout = llapi_layout_get_by_path(path, 0);
733 ASSERTF(filelayout != NULL, "errno = %d", errno);
735 rc = llapi_layout_stripe_count_get(filelayout, &fcount);
736 ASSERTF(rc == 0, "errno = %d", errno);
737 rc = llapi_layout_stripe_size_get(filelayout, &fsize);
738 ASSERTF(rc == 0, "errno = %d", errno);
739 ASSERTF(fcount == dcount || dcount == LLAPI_LAYOUT_DEFAULT ||
740 dcount == LLAPI_LAYOUT_WIDE,
741 "%"PRIu64" != %"PRIu64, fcount, dcount);
742 ASSERTF(fsize == dsize, "%"PRIu64" != %"PRIu64, fsize, dsize);
744 llapi_layout_free(filelayout);
745 llapi_layout_free(deflayout);
748 /* Setting stripe count to LLAPI_LAYOUT_WIDE uses all available OSTs. */
749 #define T17FILE "t17"
750 #define T17_DESC "LLAPI_LAYOUT_WIDE is honored"
756 uint64_t osts_layout;
757 struct llapi_layout *layout;
760 snprintf(path, sizeof(path), "%s/%s", lustre_dir, T17FILE);
763 ASSERTF(rc == 0 || errno == ENOENT, "errno = %d", errno);
764 layout = llapi_layout_alloc();
765 ASSERTF(layout != NULL, "errno = %d", errno);
766 rc = llapi_layout_stripe_count_set(layout, LLAPI_LAYOUT_WIDE);
767 ASSERTF(rc == 0, "errno = %d", errno);
768 fd = llapi_layout_file_create(path, 0, 0640, layout);
769 ASSERTF(fd >= 0, "errno = %d", errno);
771 ASSERTF(rc == 0, "errno = %d", errno);
772 llapi_layout_free(layout);
774 /* Get number of available OSTs */
775 fd = open(path, O_RDONLY);
776 ASSERTF(fd >= 0, "errno = %d", errno);
777 rc = llapi_lov_get_uuids(fd, NULL, &osts_all);
778 ASSERTF(rc == 0, "rc = %d, errno = %d", rc, errno);
780 ASSERTF(rc == 0, "errno = %d", errno);
782 layout = llapi_layout_get_by_path(path, 0);
783 ASSERTF(layout != NULL, "errno = %d", errno);
784 rc = llapi_layout_stripe_count_get(layout, &osts_layout);
785 ASSERTF(osts_layout == osts_all, "%"PRIu64" != %d", osts_layout,
788 llapi_layout_free(layout);
791 /* Setting pool with "fsname.pool" notation. */
792 #define T18FILE "t18"
793 #define T18_DESC "Setting pool with fsname.pool notation"
798 struct llapi_layout *layout = llapi_layout_alloc();
800 char pool[LOV_MAXPOOLNAME*2 + 1];
801 char mypool[LOV_MAXPOOLNAME + 1] = { '\0' };
803 snprintf(pool, sizeof(pool), "lustre.%s", poolname);
805 snprintf(path, sizeof(path), "%s/%s", lustre_dir, T18FILE);
807 ASSERTF(layout != NULL, "errno = %d", errno);
810 ASSERTF(rc == 0 || errno == ENOENT, "errno = %d", errno);
812 rc = llapi_layout_pool_name_set(layout, pool);
813 ASSERTF(rc == 0, "errno = %d", errno);
815 rc = llapi_layout_pool_name_get(layout, mypool, sizeof(mypool));
816 ASSERTF(rc == 0, "errno = %d", errno);
817 rc = strcmp(mypool, poolname);
818 ASSERTF(rc == 0, "%s != %s", mypool, poolname);
819 fd = llapi_layout_file_create(path, 0, 0640, layout);
820 ASSERTF(fd >= 0, "errno = %d", errno);
822 ASSERTF(rc == 0, "errno = %d", errno);
824 llapi_layout_free(layout);
826 layout = llapi_layout_get_by_path(path, 0);
827 ASSERTF(layout != NULL, "errno = %d", errno);
828 rc = llapi_layout_pool_name_get(layout, mypool, sizeof(mypool));
829 ASSERTF(rc == 0, "errno = %d", errno);
830 rc = strcmp(mypool, poolname);
831 ASSERTF(rc == 0, "%s != %s", mypool, poolname);
832 llapi_layout_free(layout);
835 #define T19_DESC "Maximum length pool name is NULL-terminated"
838 struct llapi_layout *layout;
839 char *name = "0123456789abcde";
840 char mypool[LOV_MAXPOOLNAME + 1] = { '\0' };
843 layout = llapi_layout_alloc();
844 ASSERTF(layout != NULL, "errno = %d", errno);
845 rc = llapi_layout_pool_name_set(layout, name);
846 ASSERTF(rc == 0, "errno = %d", errno);
847 rc = llapi_layout_pool_name_get(layout, mypool, sizeof(mypool));
848 ASSERTF(strlen(name) == strlen(mypool), "name = %s, str = %s", name,
850 llapi_layout_free(layout);
853 #define T20FILE "t20"
854 #define T20_DESC "LLAPI_LAYOUT_DEFAULT is honored"
859 struct llapi_layout *deflayout;
860 struct llapi_layout *filelayout;
867 snprintf(path, sizeof(path), "%s/%s", lustre_dir, T20FILE);
870 ASSERTF(rc == 0 || errno == ENOENT, "errno = %d", errno);
872 filelayout = llapi_layout_alloc();
873 ASSERTF(filelayout != NULL, "errno = %d", errno);
875 rc = llapi_layout_stripe_size_set(filelayout, LLAPI_LAYOUT_DEFAULT);
876 ASSERTF(rc == 0, "rc = %d, errno = %d", rc, errno);
878 rc = llapi_layout_stripe_count_set(filelayout, LLAPI_LAYOUT_DEFAULT);
879 ASSERTF(rc == 0, "rc = %d, errno = %d", rc, errno);
881 fd = llapi_layout_file_create(path, 0, 0640, filelayout);
882 ASSERTF(fd >= 0, "errno = %d", errno);
885 ASSERTF(rc == 0, "errno = %d", errno);
887 llapi_layout_free(filelayout);
889 deflayout = llapi_layout_get_by_path(lustre_dir, LAYOUT_GET_EXPECTED);
890 ASSERTF(deflayout != NULL, "errno = %d", errno);
892 filelayout = llapi_layout_get_by_path(path, 0);
893 ASSERTF(filelayout != NULL, "errno = %d", errno);
895 rc = llapi_layout_stripe_count_get(filelayout, &fcount);
896 ASSERTF(rc == 0, "errno = %d", errno);
897 rc = llapi_layout_stripe_count_get(deflayout, &dcount);
898 ASSERTF(rc == 0, "errno = %d", errno);
899 ASSERTF(fcount == dcount || dcount == LLAPI_LAYOUT_DEFAULT ||
900 dcount == LLAPI_LAYOUT_WIDE,
901 "%"PRIu64" != %"PRIu64, fcount, dcount);
903 rc = llapi_layout_stripe_size_get(filelayout, &fsize);
904 ASSERTF(rc == 0, "errno = %d", errno);
905 rc = llapi_layout_stripe_size_get(deflayout, &dsize);
906 ASSERTF(rc == 0, "errno = %d", errno);
907 ASSERTF(fsize == dsize, "%"PRIu64" != %"PRIu64, fsize, dsize);
909 llapi_layout_free(filelayout);
910 llapi_layout_free(deflayout);
913 #define T21_DESC "llapi_layout_file_create fails for non-Lustre file"
916 struct llapi_layout *layout;
917 char template[PATH_MAX];
921 snprintf(template, sizeof(template), "%s/XXXXXX", P_tmpdir);
922 fd = mkstemp(template);
923 ASSERTF(fd >= 0, "template = %s, errno = %d", template, errno);
925 ASSERTF(rc == 0, "errno = %d", fd);
926 rc = unlink(template);
927 ASSERTF(rc == 0, "errno = %d", errno);
929 layout = llapi_layout_alloc();
930 ASSERTF(layout != NULL, "errno = %d", errno);
932 fd = llapi_layout_file_create(template, 0, 0640, layout);
933 ASSERTF(fd == -1 && errno == ENOTTY,
934 "fd = %d, errno = %d, template = %s", fd, errno, template);
935 llapi_layout_free(layout);
938 #define T22FILE "t22"
939 #define T22_DESC "llapi_layout_file_create applied mode correctly"
946 mode_t mode_in = 0640;
950 snprintf(path, sizeof(path), "%s/%s", lustre_dir, T22FILE);
953 ASSERTF(rc == 0 || errno == ENOENT, "errno = %d", errno);
955 umask_orig = umask(S_IWGRP | S_IWOTH);
957 fd = llapi_layout_file_create(path, 0, mode_in, NULL);
958 ASSERTF(fd >= 0, "errno = %d", errno);
960 (void) umask(umask_orig);
963 ASSERTF(rc == 0, "errno = %d", errno);
966 ASSERTF(rc == 0, "errno = %d", fd);
968 mode_out = st.st_mode & ~S_IFMT;
969 ASSERTF(mode_in == mode_out, "%o != %o", mode_in, mode_out);
972 #define T23_DESC "llapi_layout_get_by_path fails for non-Lustre file"
975 struct llapi_layout *layout;
976 char template[PATH_MAX];
980 snprintf(template, sizeof(template), "%s/XXXXXX", P_tmpdir);
981 fd = mkstemp(template);
982 ASSERTF(fd >= 0, "template = %s, errno = %d", template, errno);
984 ASSERTF(rc == 0, "errno = %d", fd);
986 layout = llapi_layout_get_by_path(template, 0);
987 ASSERTF(layout == NULL && errno == ENOTTY,
988 "errno = %d, template = %s", errno, template);
990 rc = unlink(template);
991 ASSERTF(rc == 0, "errno = %d", errno);
994 /* llapi_layout_get_by_path(path, LAYOUT_GET_EXPECTED) returns expected layout
995 * for file with unspecified layout. */
996 #define T24FILE "t24"
997 #define T24_DESC "LAYOUT_GET_EXPECTED works with existing file"
1002 struct llapi_layout *layout;
1006 char path[PATH_MAX];
1008 snprintf(path, sizeof(path), "%s/%s", lustre_dir, T24FILE);
1011 ASSERTF(rc >= 0 || errno == ENOENT, "errno = %d", errno);
1012 fd = open(path, O_CREAT, 0640);
1013 ASSERTF(fd >= 0, "errno = %d", errno);
1015 ASSERTF(rc == 0, "errno = %d", errno);
1017 layout = llapi_layout_get_by_path(path, LAYOUT_GET_EXPECTED);
1018 ASSERTF(layout != NULL, "errno = %d\n", errno);
1020 rc = llapi_layout_stripe_count_get(layout, &count);
1021 ASSERTF(rc == 0, "errno = %d\n", errno);
1022 ASSERTF(count != LLAPI_LAYOUT_DEFAULT, "expected literal value");
1024 rc = llapi_layout_stripe_size_get(layout, &size);
1025 ASSERTF(rc == 0, "errno = %d\n", errno);
1026 ASSERTF(size != LLAPI_LAYOUT_DEFAULT, "expected literal value");
1028 rc = llapi_layout_pattern_get(layout, &pattern);
1029 ASSERTF(rc == 0, "errno = %d\n", errno);
1030 ASSERTF(pattern != LLAPI_LAYOUT_DEFAULT, "expected literal value");
1032 llapi_layout_free(layout);
1035 /* llapi_layout_get_by_path(path, LAYOUT_GET_EXPECTED) returns expected layout
1036 * for directory with unspecified layout. */
1037 #define T25DIR "d25"
1038 #define T25_DESC "LAYOUT_GET_EXPECTED works with directory"
1042 struct llapi_layout *layout;
1048 snprintf(dir, sizeof(dir), "%s/%s", lustre_dir, T25DIR);
1051 ASSERTF(rc >= 0 || errno == ENOENT, "errno = %d", errno);
1052 rc = mkdir(dir, 0750);
1053 ASSERTF(rc == 0, "errno = %d", errno);
1055 layout = llapi_layout_get_by_path(dir, LAYOUT_GET_EXPECTED);
1056 ASSERTF(layout != NULL, "errno = %d\n", errno);
1058 rc = llapi_layout_stripe_count_get(layout, &count);
1059 ASSERTF(rc == 0, "errno = %d\n", errno);
1060 ASSERTF(count != LLAPI_LAYOUT_DEFAULT, "expected literal value");
1062 rc = llapi_layout_stripe_size_get(layout, &size);
1063 ASSERTF(rc == 0, "errno = %d\n", errno);
1064 ASSERTF(size != LLAPI_LAYOUT_DEFAULT, "expected literal value");
1066 rc = llapi_layout_pattern_get(layout, &pattern);
1067 ASSERTF(rc == 0, "errno = %d\n", errno);
1068 ASSERTF(pattern != LLAPI_LAYOUT_DEFAULT, "expected literal value");
1070 llapi_layout_free(layout);
1073 /* llapi_layout_get_by_path(path, LAYOUT_GET_EXPECTED) correctly combines
1074 * specified attributes of parent directory with attributes filesystem root. */
1075 #define T26DIR "d26"
1076 #define T26_DESC "LAYOUT_GET_EXPECTED partially specified parent"
1077 #define T26_STRIPE_SIZE (1048576 * 4)
1081 struct llapi_layout *layout;
1082 const char *lfs = getenv("LFS");
1087 char cmd[PATH_MAX + 64];
1089 snprintf(dir, sizeof(dir), "%s/%s", lustre_dir, T26DIR);
1091 ASSERTF(rc >= 0 || errno == ENOENT, "errno = %d", errno);
1092 rc = mkdir(dir, 0750);
1093 ASSERTF(rc == 0, "errno = %d", errno);
1096 lfs = "/usr/bin/lfs";
1098 snprintf(cmd, sizeof(cmd), "%s setstripe -S %d %s", lfs,
1099 T26_STRIPE_SIZE, dir);
1101 ASSERTF(rc == 0, "system(%s): exit status %d", cmd, WEXITSTATUS(rc));
1103 layout = llapi_layout_get_by_path(dir, LAYOUT_GET_EXPECTED);
1104 ASSERTF(layout != NULL, "errno = %d\n", errno);
1106 rc = llapi_layout_stripe_count_get(layout, &count);
1107 ASSERTF(rc == 0, "errno = %d\n", errno);
1108 ASSERTF(count != LLAPI_LAYOUT_DEFAULT, "expected literal value");
1110 rc = llapi_layout_stripe_size_get(layout, &size);
1111 ASSERTF(rc == 0, "errno = %d\n", errno);
1112 ASSERTF(size == T26_STRIPE_SIZE, "size = %"PRIu64, size);
1114 rc = llapi_layout_pattern_get(layout, &pattern);
1115 ASSERTF(rc == 0, "errno = %d\n", errno);
1116 ASSERTF(pattern != LLAPI_LAYOUT_DEFAULT, "expected literal value");
1118 llapi_layout_free(layout);
1121 /* llapi_layout_get_by_path(path, LAYOUT_GET_EXPECTED) work with
1122 * non existing file. */
1123 #define T27DIR "d27"
1124 #define T27_DESC "LAYOUT_GET_EXPECTED with non existing file"
1125 #define T27_STRIPE_SIZE (1048576 * 3)
1129 struct llapi_layout *layout;
1130 const char *lfs = getenv("LFS");
1134 char dirpath[PATH_MAX + 128];
1135 char filepath[PATH_MAX * 2];
1136 char cmd[PATH_MAX * 2];
1138 snprintf(dirpath, sizeof(dirpath) - 1, "%s/%s", lustre_dir, T27DIR);
1139 snprintf(filepath, sizeof(filepath), "%s/nonesuch", dirpath);
1141 rc = rmdir(dirpath);
1142 ASSERTF(rc >= 0 || errno == ENOENT, "errno = %d", errno);
1143 rc = mkdir(dirpath, 0750);
1144 ASSERTF(rc == 0, "errno = %d", errno);
1147 lfs = "/usr/bin/lfs";
1149 snprintf(cmd, sizeof(cmd), "%s setstripe -S %d %s", lfs,
1150 T27_STRIPE_SIZE, dirpath);
1152 ASSERTF(rc == 0, "system(%s): exit status %d", cmd, WEXITSTATUS(rc));
1154 layout = llapi_layout_get_by_path(filepath, LAYOUT_GET_EXPECTED);
1155 ASSERTF(layout != NULL, "errno = %d\n", errno);
1157 rc = llapi_layout_stripe_count_get(layout, &count);
1158 ASSERTF(rc == 0, "errno = %d\n", errno);
1159 ASSERTF(count != LLAPI_LAYOUT_DEFAULT, "expected literal value");
1161 rc = llapi_layout_stripe_size_get(layout, &size);
1162 ASSERTF(rc == 0, "errno = %d\n", errno);
1163 ASSERTF(size == T27_STRIPE_SIZE, "size = %"PRIu64, size);
1165 rc = llapi_layout_pattern_get(layout, &pattern);
1166 ASSERTF(rc == 0, "errno = %d\n", errno);
1167 ASSERTF(pattern != LLAPI_LAYOUT_DEFAULT, "expected literal value");
1169 llapi_layout_free(layout);
1172 /* llapi_layout_stripe_count_get returns LLAPI_LAYOUT_WIDE for a directory
1173 * with a stripe_count of -1. */
1174 #define T28DIR "d28"
1175 #define T28_DESC "LLAPI_LAYOUT_WIDE returned as expected"
1179 struct llapi_layout *layout;
1180 const char *lfs = getenv("LFS");
1182 char dirpath[PATH_MAX];
1183 char cmd[PATH_MAX + 64];
1185 snprintf(dirpath, sizeof(dirpath), "%s/%s", lustre_dir, T28DIR);
1187 rc = rmdir(dirpath);
1188 ASSERTF(rc >= 0 || errno == ENOENT, "errno = %d", errno);
1189 rc = mkdir(dirpath, 0750);
1190 ASSERTF(rc == 0, "errno = %d", errno);
1193 lfs = "/usr/bin/lfs";
1195 snprintf(cmd, sizeof(cmd), "%s setstripe -c -1 %s", lfs, dirpath);
1197 ASSERTF(rc == 0, "system(%s): exit status %d", cmd, WEXITSTATUS(rc));
1199 layout = llapi_layout_get_by_path(dirpath, 0);
1200 ASSERTF(layout != NULL, "errno = %d\n", errno);
1202 rc = llapi_layout_stripe_count_get(layout, &count);
1203 ASSERTF(rc == 0, "errno = %d\n", errno);
1204 ASSERTF(count == LLAPI_LAYOUT_WIDE, "count = %"PRIu64"\n", count);
1206 llapi_layout_free(layout);
1209 #define T29FILE "f29"
1210 #define T29_DESC "set ost index to non-zero stripe number"
1214 uint64_t ost0, ost1, nost;
1215 struct llapi_layout *layout;
1216 char path[PATH_MAX];
1221 layout = llapi_layout_alloc();
1222 ASSERTF(layout != NULL, "errno %d", errno);
1224 snprintf(path, sizeof(path), "%s/%s", lustre_dir, T29FILE);
1227 ASSERTF(rc >= 0 || errno == ENOENT, "errno = %d", errno);
1229 /* set ost index to LLAPI_LAYOUT_IDX_MAX should fail */
1230 rc = llapi_layout_ost_index_set(layout, 1, LLAPI_LAYOUT_IDX_MAX);
1231 ASSERTF(rc == -1 && errno == EINVAL, "rc = %d, errno = %d\n",
1234 /* specify ost index partially */
1235 rc = llapi_layout_ost_index_set(layout, 1, 0);
1236 ASSERTF(rc == 0, "errno = %d", errno);
1238 /* create a partially specified layout will fail */
1239 fd = llapi_layout_file_create(path, 0, 0660, layout);
1240 ASSERTF(fd == -1 && errno == EINVAL, "path = %s, fd = %d, errno = %d",
1244 ASSERTF(rc >= 0 || errno == ENOENT, "errno = %d", errno);
1246 /* specify all stripes */
1247 rc = llapi_layout_ost_index_set(layout, 0, 1);
1248 ASSERTF(rc == 0, "errno = %d", errno);
1251 fd = llapi_layout_file_create(path, 0, 0660, layout);
1252 ASSERTF(fd >= 0, "path = %s, fd = %d, errno = %d", path, fd, errno);
1255 ASSERTF(rc == 0, "errno = %d", errno);
1256 llapi_layout_free(layout);
1258 /* get layout from file */
1259 layout = llapi_layout_get_by_path(path, 0);
1260 ASSERTF(layout != NULL, "errno = %d", errno);
1262 rc = llapi_layout_ost_index_get(layout, 0, &ost0);
1263 ASSERTF(rc == 0, "errno = %d", errno);
1264 rc = llapi_layout_ost_index_get(layout, 1, &ost1);
1265 ASSERTF(rc == 0, "errno = %d", errno);
1266 ASSERTF(ost0 == 1, "%"PRIu64" != %d", ost0, 1);
1267 ASSERTF(ost1 == 0, "%"PRIu64" != %d", ost1, 0);
1268 llapi_layout_free(layout);
1270 /* specify more ost indexes to test realloc */
1272 layout = llapi_layout_alloc();
1273 ASSERTF(layout != NULL, "errno %d", errno);
1274 for (i = 0; i < LOV_MAX_STRIPE_COUNT; i++) {
1275 rc = llapi_layout_ost_index_set(layout, i, nost);
1276 ASSERTF(rc == 0, "errno = %d", errno);
1277 rc = llapi_layout_ost_index_get(layout, i, &ost0);
1278 ASSERTF(rc == 0, "errno = %d", errno);
1280 if (nost == num_osts)
1285 for (i = 0; i < LOV_MAX_STRIPE_COUNT; i++) {
1286 rc = llapi_layout_ost_index_get(layout, i, &ost0);
1287 ASSERTF(rc == 0, "errno = %d", errno);
1288 ASSERTF(ost0 == nost, "ost=%"PRIu64" nost=%"PRIu64"",
1291 if (nost == num_osts)
1294 llapi_layout_free(layout);
1297 layout = llapi_layout_alloc();
1298 ASSERTF(layout != NULL, "errno %d", errno);
1299 for (i = LOV_MAX_STRIPE_COUNT-1; i >= 0; i--) {
1300 rc = llapi_layout_ost_index_set(layout, i, nost);
1301 ASSERTF(rc == 0, "errno = %d", errno);
1302 rc = llapi_layout_ost_index_get(layout, i, &ost0);
1303 ASSERTF(rc == 0, "errno = %d", errno);
1305 if (nost == num_osts)
1310 for (i = LOV_MAX_STRIPE_COUNT-1; i <= 0; i--) {
1311 rc = llapi_layout_ost_index_get(layout, i, &ost0);
1312 ASSERTF(rc == 0, "errno = %d", errno);
1313 ASSERTF(ost0 == nost, "ost=%"PRIu64", nost=%"PRIu64"",
1316 if (nost == num_osts)
1319 llapi_layout_free(layout);
1322 #define T30FILE "f30"
1323 #define T30_DESC "create composite file, traverse components"
1327 uint64_t start[3], end[3];
1329 struct llapi_layout *layout;
1330 char path[PATH_MAX];
1333 end[0] = 64 * 1024 * 1024; /* 64m */
1335 end[1] = 1 * 1024 * 1024 * 1024; /* 1G */
1337 end[2] = LUSTRE_EOF;
1342 snprintf(path, sizeof(path), "%s/%s", lustre_dir, T30FILE);
1345 ASSERTF(rc >= 0 || errno == ENOENT, "errno = %d", errno);
1347 layout = llapi_layout_alloc();
1348 ASSERTF(layout != NULL, "errno %d", errno);
1350 rc = llapi_layout_stripe_count_set(layout, 1);
1351 ASSERTF(rc == 0, "errno %d", errno);
1353 /* add component without adjusting previous component's extent
1355 rc = llapi_layout_comp_add(layout);
1356 ASSERTF(rc == -1 && errno == EINVAL, "rc %d, errno %d", rc, errno);
1358 rc = llapi_layout_comp_extent_set(layout, start[0], end[0]);
1359 ASSERTF(rc == 0, "errno %d", errno);
1361 rc = llapi_layout_comp_add(layout);
1362 ASSERTF(rc == 0, "errno %d", errno);
1364 /* set non-contiguous extent will fail */
1365 rc = llapi_layout_comp_extent_set(layout, end[0] * 2, end[1]);
1366 ASSERTF(rc == -1 && errno == EINVAL, "rc %d, errno %d", rc, errno);
1368 rc = llapi_layout_comp_extent_set(layout, start[1], end[1]);
1369 ASSERTF(rc == 0, "errno %d", errno);
1371 rc = llapi_layout_comp_add(layout);
1372 ASSERTF(rc == 0, "errno %d", errno);
1374 rc = llapi_layout_comp_extent_set(layout, start[2], end[2]);
1375 ASSERTF(rc == 0, "errno %d", errno);
1377 /* create composite file */
1378 fd = llapi_layout_file_create(path, 0, 0660, layout);
1379 ASSERTF(fd >= 0, "path = %s, fd = %d, errno = %d", path, fd, errno);
1381 llapi_layout_free(layout);
1383 /* traverse & verify all components */
1384 layout = llapi_layout_get_by_path(path, 0);
1385 ASSERTF(layout != NULL, "errno = %d", errno);
1387 /* current component should be the tail component */
1388 rc = llapi_layout_comp_extent_get(layout, &s, &e);
1389 ASSERTF(rc == 0, "errno %d", errno);
1390 ASSERTF(s == start[2] && e == end[2],
1391 "s: %"PRIu64", e: %"PRIu64"", s, e);
1393 rc = llapi_layout_comp_use(layout, LLAPI_LAYOUT_COMP_USE_FIRST);
1394 ASSERTF(rc == 0, "rc %d, errno %d", rc, errno);
1396 /* delete non-tail component will fail */
1397 rc = llapi_layout_comp_del(layout);
1398 ASSERTF(rc == -1 && errno == EINVAL, "rc %d, errno %d", rc, errno);
1400 rc = llapi_layout_comp_extent_get(layout, &s, &e);
1401 ASSERTF(rc == 0, "errno %d", errno);
1402 ASSERTF(s == start[0] && e == end[0],
1403 "s: %"PRIu64", e: %"PRIu64"", s, e);
1405 rc = llapi_layout_comp_use(layout, LLAPI_LAYOUT_COMP_USE_NEXT);
1406 ASSERTF(rc == 0, "rc %d, errno %d", rc, errno);
1408 rc = llapi_layout_comp_extent_get(layout, &s, &e);
1409 ASSERTF(rc == 0, "errno %d", errno);
1410 ASSERTF(s == start[1] && e == end[1],
1411 "s: %"PRIu64", e: %"PRIu64"", s, e);
1413 rc = llapi_layout_comp_use(layout, LLAPI_LAYOUT_COMP_USE_NEXT);
1414 ASSERTF(rc == 0, "rc %d, errno %d", rc, errno);
1416 rc = llapi_layout_comp_del(layout);
1417 ASSERTF(rc == 0, "errno %d", errno);
1419 llapi_layout_free(layout);
1422 #define T31FILE "f31"
1423 #define T31_DESC "add/delete component to/from existing file"
1427 uint64_t start[2], end[2];
1430 struct llapi_layout *layout;
1431 char path[PATH_MAX];
1434 end[0] = 64 * 1024 * 1024; /* 64m */
1436 end[1] = LUSTRE_EOF;
1441 snprintf(path, sizeof(path), "%s/%s", lustre_dir, T31FILE);
1444 ASSERTF(rc >= 0 || errno == ENOENT, "errno = %d", errno);
1446 layout = llapi_layout_alloc();
1447 ASSERTF(layout != NULL, "errno %d", errno);
1449 rc = llapi_layout_stripe_count_set(layout, 1);
1450 ASSERTF(rc == 0, "errno %d", errno);
1452 rc = llapi_layout_comp_extent_set(layout, start[0], end[0]);
1453 ASSERTF(rc == 0, "errno %d", errno);
1455 /* create composite file */
1456 fd = llapi_layout_file_create(path, 0, 0660, layout);
1457 ASSERTF(fd >= 0, "path = %s, fd = %d, errno = %d", path, fd, errno);
1458 llapi_layout_free(layout);
1460 layout = llapi_layout_alloc();
1461 ASSERTF(layout != NULL, "errno %d", errno);
1463 rc = llapi_layout_stripe_count_set(layout, 2);
1464 ASSERTF(rc == 0, "errno %d", errno);
1466 rc = llapi_layout_comp_extent_set(layout, start[1], end[1]);
1467 ASSERTF(rc == 0, "errno %d", errno);
1469 /* add comopnent to existing file */
1470 rc = llapi_layout_file_comp_add(path, layout);
1471 ASSERTF(rc == 0, "errno %d", errno);
1472 llapi_layout_free(layout);
1474 /* verify the composite layout after adding */
1475 layout = llapi_layout_get_by_path(path, 0);
1476 ASSERTF(layout != NULL, "errno = %d", errno);
1478 rc = llapi_layout_comp_use(layout, LLAPI_LAYOUT_COMP_USE_FIRST);
1479 ASSERTF(rc == 0, "rc %d, errno %d", rc, errno);
1482 rc = llapi_layout_comp_extent_get(layout, &s, &e);
1483 ASSERTF(rc == 0 && i < 2, "i %d, errno %d", i, errno);
1484 ASSERTF(s == start[i] && e == end[i],
1485 "i: %d s: %"PRIu64", e: %"PRIu64"", i, s, e);
1487 rc = llapi_layout_comp_id_get(layout, &id[i]);
1488 ASSERTF(rc == 0 && id[i] != 0, "i %d, errno %d, id %d",
1491 rc = llapi_layout_comp_use(layout, LLAPI_LAYOUT_COMP_USE_NEXT);
1492 ASSERTF(rc == 0 || i == 1, "i=%d rc=%d errno=%d", i, rc, errno);
1496 /* Verify reverse iteration gives the same IDs as forward iteration */
1497 rc = llapi_layout_comp_use(layout, LLAPI_LAYOUT_COMP_USE_LAST);
1498 ASSERTF(rc == 0, "rc %d, errno %d", rc, errno);
1503 rc = llapi_layout_comp_id_get(layout, &comp_id);
1504 ASSERTF(rc == 0 && comp_id == id[i],
1505 "i %d, errno %d, id[] %u/%u", i, errno, id[i], comp_id);
1507 rc = llapi_layout_comp_use(layout, LLAPI_LAYOUT_COMP_USE_PREV);
1508 ASSERTF(rc == 0 || i == 0, "i=%d rc=%d errno=%d", i, rc, errno);
1511 llapi_layout_free(layout);
1513 /* delete non-tail component will fail */
1514 rc = llapi_layout_file_comp_del(path, id[0], 0);
1515 ASSERTF(rc < 0 && errno == EINVAL, "rc %d, errno %d", rc, errno);
1517 rc = llapi_layout_file_comp_del(path, id[1], 0);
1518 ASSERTF(rc == 0, "rc %d, errno %d", rc, errno);
1520 /* verify the composite layout after deleting */
1521 layout = llapi_layout_get_by_path(path, 0);
1522 ASSERTF(layout != NULL, "errno = %d", errno);
1524 rc = llapi_layout_comp_use(layout, LLAPI_LAYOUT_COMP_USE_FIRST);
1525 ASSERTF(rc == 0, "rc %d, errno %d", rc, errno);
1527 rc = llapi_layout_comp_extent_get(layout, &s, &e);
1528 ASSERTF(rc == 0, "errno %d", errno);
1529 ASSERTF(s == start[0] && e == end[0],
1530 "s: %"PRIu64", e: %"PRIu64"", s, e);
1533 #define T32FILE "t32"
1534 #define T32_STRIPE_COUNT (num_osts*2)
1535 #define T32_DESC "Test overstriping with layout_file_create"
1541 struct llapi_layout *layout = llapi_layout_alloc();
1542 void *lmdbuf = NULL;
1543 struct lov_user_md *lmd;
1544 char path[PATH_MAX];
1546 ASSERTF(layout != NULL, "errno %d", errno);
1548 /* Maximum possible, to be on the safe side - num_osts could be large */
1549 lmdbuf = malloc(XATTR_SIZE_MAX);
1550 ASSERTF(lmdbuf != NULL, "errno %d", errno);
1553 snprintf(path, sizeof(path), "%s/%s", lustre_dir, T32FILE);
1556 ASSERTF(rc >= 0 || errno == ENOENT, "errno = %d", errno);
1559 rc = llapi_layout_stripe_count_set(layout, T32_STRIPE_COUNT);
1560 ASSERTF(rc == 0, "errno = %d", errno);
1561 rc = llapi_layout_stripe_count_get(layout, &count);
1562 ASSERTF(rc == 0 && count == T32_STRIPE_COUNT, "%"PRIu64" != %d", count,
1565 rc = llapi_layout_pattern_set(layout, LLAPI_LAYOUT_OVERSTRIPING);
1566 ASSERTF(rc == 0, "errno = %d", errno);
1569 fd = llapi_layout_file_create(path, 0, 0660, layout);
1570 ASSERTF(fd >= 0, "path = %s, errno = %d", path, errno);
1572 rc = ioctl(fd, LL_IOC_LOV_GETSTRIPE_NEW, lmdbuf);
1573 ASSERTF(rc == 0, "errno = %d", errno);
1575 count = lmd->lmm_stripe_count;
1576 ASSERTF(count == T32_STRIPE_COUNT,
1577 "stripe count (%"PRIu64") not equal to expected (%d)",
1578 count, T32_STRIPE_COUNT);
1581 ASSERTF(rc == 0, "errno = %d", errno);
1582 llapi_layout_free(layout);
1586 #define T33FILE "t33"
1587 #define T33_STRIPE_COUNT (num_osts*2)
1588 #define T33_DESC "Test overstriping with llapi_file_open"
1594 void *lmdbuf = NULL;
1595 struct lov_user_md *lmd;
1596 char path[PATH_MAX];
1598 /* Maximum possible, to be on the safe side - num_osts could be large */
1599 lmdbuf = malloc(XATTR_SIZE_MAX);
1600 ASSERTF(lmdbuf != NULL, "errno %d", errno);
1603 snprintf(path, sizeof(path), "%s/%s", lustre_dir, T33FILE);
1606 ASSERTF(rc >= 0 || errno == ENOENT, "errno = %d", errno);
1608 fd = llapi_file_open(path, O_CREAT | O_RDWR, 0660, 0, -1, num_osts*2,
1609 LOV_PATTERN_RAID0 | LOV_PATTERN_OVERSTRIPING);
1610 ASSERTF(fd >= 0, "path = %s, errno = %d", path, errno);
1612 rc = ioctl(fd, LL_IOC_LOV_GETSTRIPE_NEW, lmdbuf);
1613 ASSERTF(rc == 0, "errno = %d", errno);
1615 count = lmd->lmm_stripe_count;
1616 ASSERTF(count == T33_STRIPE_COUNT,
1617 "stripe count (%"PRIu64") not equal to expected (%d)",
1618 count, T33_STRIPE_COUNT);
1621 ASSERTF(rc == 0, "errno = %d", errno);
1625 #define TEST_DESC_LEN 80
1626 struct test_tbl_entry {
1627 void (*tte_fn)(void);
1628 char tte_desc[TEST_DESC_LEN];
1632 static struct test_tbl_entry test_tbl[] = {
1633 { .tte_fn = &test0, .tte_desc = T0_DESC, .tte_skip = false },
1634 { .tte_fn = &test1, .tte_desc = T1_DESC, .tte_skip = false },
1635 { .tte_fn = &test2, .tte_desc = T2_DESC, .tte_skip = false },
1636 { .tte_fn = &test3, .tte_desc = T3_DESC, .tte_skip = false },
1637 { .tte_fn = &test4, .tte_desc = T4_DESC, .tte_skip = false },
1638 { .tte_fn = &test5, .tte_desc = T5_DESC, .tte_skip = false },
1639 { .tte_fn = &test6, .tte_desc = T6_DESC, .tte_skip = false },
1640 { .tte_fn = &test7, .tte_desc = T7_DESC, .tte_skip = false },
1641 { .tte_fn = &test8, .tte_desc = T8_DESC, .tte_skip = false },
1642 { .tte_fn = &test9, .tte_desc = T9_DESC, .tte_skip = false },
1643 { .tte_fn = &test10, .tte_desc = T10_DESC, .tte_skip = false },
1644 { .tte_fn = &test11, .tte_desc = T11_DESC, .tte_skip = false },
1645 { .tte_fn = &test12, .tte_desc = T12_DESC, .tte_skip = false },
1646 { .tte_fn = &test13, .tte_desc = T13_DESC, .tte_skip = false },
1647 { .tte_fn = &test14, .tte_desc = T14_DESC, .tte_skip = false },
1648 { .tte_fn = &test15, .tte_desc = T15_DESC, .tte_skip = false },
1649 { .tte_fn = &test16, .tte_desc = T16_DESC, .tte_skip = false },
1650 { .tte_fn = &test17, .tte_desc = T17_DESC, .tte_skip = false },
1651 { .tte_fn = &test18, .tte_desc = T18_DESC, .tte_skip = false },
1652 { .tte_fn = &test19, .tte_desc = T19_DESC, .tte_skip = false },
1653 { .tte_fn = &test20, .tte_desc = T20_DESC, .tte_skip = false },
1654 { .tte_fn = &test21, .tte_desc = T21_DESC, .tte_skip = false },
1655 { .tte_fn = &test22, .tte_desc = T22_DESC, .tte_skip = false },
1656 { .tte_fn = &test23, .tte_desc = T23_DESC, .tte_skip = false },
1657 { .tte_fn = &test24, .tte_desc = T24_DESC, .tte_skip = false },
1658 { .tte_fn = &test25, .tte_desc = T25_DESC, .tte_skip = false },
1659 { .tte_fn = &test26, .tte_desc = T26_DESC, .tte_skip = false },
1660 { .tte_fn = &test27, .tte_desc = T27_DESC, .tte_skip = false },
1661 { .tte_fn = &test28, .tte_desc = T28_DESC, .tte_skip = false },
1662 { .tte_fn = &test29, .tte_desc = T29_DESC, .tte_skip = false },
1663 { .tte_fn = &test30, .tte_desc = T30_DESC, .tte_skip = false },
1664 { .tte_fn = &test31, .tte_desc = T31_DESC, .tte_skip = false },
1665 { .tte_fn = &test32, .tte_desc = T32_DESC, .tte_skip = false },
1666 { .tte_fn = &test32, .tte_desc = T33_DESC, .tte_skip = false },
1669 #define NUM_TESTS (sizeof(test_tbl) / sizeof(struct test_tbl_entry))
1671 void print_test_desc(int test_num, const char *test_desc, const char *status)
1675 printf(" test %2d: %s ", test_num, test_desc);
1676 for (i = 0; i < TEST_DESC_LEN - strlen(test_desc); i++)
1678 printf(" %s\n", status);
1681 /* This function runs a single test by forking the process. This way,
1682 * if there is a segfault during a test, the test program won't crash. */
1683 int test(void (*test_fn)(), const char *test_desc, bool test_skip, int test_num)
1687 char status_buf[128];
1690 print_test_desc(test_num, test_desc, "skip");
1696 ERROR("cannot fork: %s", strerror(errno));
1697 } else if (pid > 0) {
1700 /* Non-zero value indicates failure. */
1703 strncpy(status_buf, "pass", sizeof(status_buf));
1704 } else if WIFSIGNALED(status) {
1705 snprintf(status_buf, sizeof(status_buf),
1706 "fail (exit status %d, killed by SIG%d)",
1707 WEXITSTATUS(status), WTERMSIG(status));
1710 snprintf(status_buf, sizeof(status_buf),
1711 "fail (exit status %d)", WEXITSTATUS(status));
1714 print_test_desc(test_num, test_desc, status_buf);
1715 } else if (pid == 0) {
1716 /* Run the test in the child process. Exit with 0 for success,
1717 * non-zero for failure */
1725 /* 'str_tests' are the tests to be skipped, such as "1,3,4,.." */
1726 static void set_tests_skipped(char *str_tests)
1728 char *ptr = str_tests;
1731 if (ptr == NULL || strlen(ptr) == 0)
1734 while (*ptr != '\0') {
1735 tstno = strtoul(ptr, &ptr, 0);
1736 if (tstno >= 0 && tstno < NUM_TESTS)
1737 test_tbl[tstno].tte_skip = true;
1745 static void process_args(int argc, char *argv[])
1749 while ((c = getopt(argc, argv, "d:p:o:s:")) != -1) {
1752 lustre_dir = optarg;
1758 num_osts = atoi(optarg);
1761 set_tests_skipped(optarg);
1764 fprintf(stderr, "Unknown option '%c'\n", optopt);
1770 int main(int argc, char *argv[])
1777 llapi_msg_set_level(LLAPI_MSG_OFF);
1779 process_args(argc, argv);
1780 if (lustre_dir == NULL)
1781 lustre_dir = "/mnt/lustre";
1782 if (poolname == NULL)
1783 poolname = "testpool";
1788 DIE("Error: at least 2 OSTS are required\n");
1790 if (stat(lustre_dir, &s) < 0)
1791 DIE("cannot stat %s: %s\n", lustre_dir, strerror(errno));
1792 else if (!S_ISDIR(s.st_mode))
1793 DIE("%s: not a directory\n", lustre_dir);
1795 rc = llapi_search_fsname(lustre_dir, fsname);
1797 fprintf(stderr, "Error: %s: not a Lustre filesystem\n",
1802 /* Play nice with Lustre test scripts. Non-line buffered output
1803 * stream under I/O redirection may appear incorrectly. */
1804 setvbuf(stdout, NULL, _IOLBF, 0);
1806 for (i = 0; i < NUM_TESTS; i++) {
1807 struct test_tbl_entry *tst = &test_tbl[i];
1808 if (test(tst->tte_fn, tst->tte_desc, tst->tte_skip, i) != 0)