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 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"
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 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"
175 snprintf(path, sizeof(path), "%s/%s", lustre_dir, T0FILE);
176 struct llapi_layout *layout = llapi_layout_get_by_path(path, 0);
177 ASSERTF(layout != NULL, "errno = %d", errno);
178 __test1_helper(layout);
179 llapi_layout_free(layout);
182 #define T2_DESC "Read test0 file by FD and verify attributes"
189 snprintf(path, sizeof(path), "%s/%s", lustre_dir, T0FILE);
191 fd = open(path, O_RDONLY);
192 ASSERTF(fd >= 0, "open(%s): errno = %d", path, errno);
194 struct llapi_layout *layout = llapi_layout_get_by_fd(fd, 0);
195 ASSERTF(layout != NULL, "errno = %d", errno);
198 ASSERTF(rc == 0, "close(%s): errno = %d", path, errno);
200 __test1_helper(layout);
201 llapi_layout_free(layout);
204 #define T3_DESC "Read test0 file by FID and verify attributes"
208 struct llapi_layout *layout;
213 snprintf(path, sizeof(path), "%s/%s", lustre_dir, T0FILE);
215 rc = llapi_path2fid(path, &fid);
216 ASSERTF(rc == 0, "rc = %d, errno = %d", rc, errno);
217 snprintf(fidstr, sizeof(fidstr), "0x%"PRIx64":0x%x:0x%x",
218 (uint64_t)fid.f_seq, fid.f_oid, fid.f_ver);
220 layout = llapi_layout_get_by_fid(path, &fid, 0);
221 ASSERTF(layout != NULL, "fidstr = %s, errno = %d", fidstr, errno);
223 __test1_helper(layout);
224 llapi_layout_free(layout);
228 #define T4_STRIPE_COUNT 2
229 #define T4_STRIPE_SIZE 2097152
230 #define T4_DESC "Verify compatibility with 'lfs setstripe'"
238 const char *lfs = getenv("LFS");
239 char mypool[LOV_MAXPOOLNAME + 1] = { '\0' };
240 char cmd[PATH_MAX + 128];
243 snprintf(path, sizeof(path), "%s/%s", lustre_dir, T4FILE);
246 lfs = "/usr/bin/lfs";
249 ASSERTF(rc == 0 || errno == ENOENT, "errno = %d", errno);
251 snprintf(cmd, sizeof(cmd), "%s setstripe %s %s -c %d -S %d %s", lfs,
252 strlen(poolname) > 0 ? "-p" : "", poolname, T4_STRIPE_COUNT,
253 T4_STRIPE_SIZE, path);
255 ASSERTF(rc == 0, "system(%s): exit status %d", cmd, WEXITSTATUS(rc));
258 struct llapi_layout *layout = llapi_layout_get_by_path(path, 0);
259 ASSERTF(layout != NULL, "errno = %d", errno);
261 rc = llapi_layout_stripe_count_get(layout, &count);
262 ASSERTF(count == T4_STRIPE_COUNT, "%"PRIu64" != %d", count,
265 rc = llapi_layout_stripe_size_get(layout, &size);
266 ASSERTF(size == T4_STRIPE_SIZE, "%"PRIu64" != %d", size,
269 rc = llapi_layout_pool_name_get(layout, mypool, sizeof(mypool));
270 ASSERTF(rc == 0, "errno = %d", errno);
271 rc = strcmp(mypool, poolname);
272 ASSERTF(rc == 0, "%s != %s", mypool, poolname);
274 rc = llapi_layout_ost_index_get(layout, 0, &ost0);
275 ASSERTF(rc == 0, "errno = %d", errno);
276 rc = llapi_layout_ost_index_get(layout, 1, &ost1);
277 ASSERTF(rc == 0, "errno = %d", errno);
278 ASSERTF(ost1 != ost0, "%"PRIu64" == %"PRIu64, ost0, ost1);
280 llapi_layout_free(layout);
284 #define T5_DESC "llapi_layout_get_by_path ENOENT handling"
289 struct llapi_layout *layout;
291 snprintf(path, sizeof(path), "%s/%s", lustre_dir, T5FILE);
294 ASSERTF(rc == 0 || errno == ENOENT, "errno = %d", errno);
297 layout = llapi_layout_get_by_path(path, 0);
298 ASSERTF(layout == NULL && errno == ENOENT, "errno = %d", errno);
301 #define T6_DESC "llapi_layout_get_by_fd EBADF handling"
305 struct llapi_layout *layout = llapi_layout_get_by_fd(9999, 0);
306 ASSERTF(layout == NULL && errno == EBADF, "errno = %d", errno);
310 #define T7_DESC "llapi_layout_get_by_path EACCES handling"
315 uid_t myuid = getuid();
317 const char *runas = getenv("RUNAS_ID");
321 snprintf(path, sizeof(path), "%s/%s", lustre_dir, T7FILE);
322 ASSERTF(myuid == 0, "myuid = %d", myuid); /* Need root for this test. */
324 /* Create file as root */
326 ASSERTF(rc == 0 || errno == ENOENT, "errno = %d", errno);
328 fd = open(path, O_CREAT, 0400);
329 ASSERTF(fd > 0, "errno = %d", errno);
331 ASSERTF(rc == 0, "errno = %d", errno);
333 /* Become unprivileged user */
336 ASSERTF(uid != 0, "runas = %s", runas);
338 pw = getpwnam("nobody");
339 ASSERTF(pw != NULL, "errno = %d", errno);
343 ASSERTF(rc == 0, "errno = %d", errno);
345 struct llapi_layout *layout = llapi_layout_get_by_path(path, 0);
346 ASSERTF(layout == NULL && errno == EACCES, "errno = %d", errno);
348 ASSERTF(rc == 0, "errno = %d", errno);
351 /* llapi_layout_get_by_path() returns default layout for file with no
352 * striping attributes. */
354 #define T8_DESC "llapi_layout_get_by_path ENODATA handling"
359 struct llapi_layout *layout;
365 snprintf(path, sizeof(path), "%s/%s", lustre_dir, T8FILE);
368 ASSERTF(rc >= 0 || errno == ENOENT, "errno = %d", errno);
369 fd = open(path, O_CREAT, 0640);
370 ASSERTF(fd >= 0, "errno = %d", errno);
372 ASSERTF(rc == 0, "errno = %d", errno);
374 layout = llapi_layout_get_by_path(path, 0);
375 ASSERTF(layout != NULL, "errno = %d\n", errno);
377 rc = llapi_layout_stripe_count_get(layout, &count);
378 ASSERTF(rc == 0, "errno = %d\n", errno);
379 ASSERTF(count == LLAPI_LAYOUT_DEFAULT, "count = %"PRIu64"\n", count);
381 rc = llapi_layout_stripe_size_get(layout, &size);
382 ASSERTF(rc == 0, "errno = %d\n", errno);
383 ASSERTF(size == LLAPI_LAYOUT_DEFAULT, "size = %"PRIu64"\n", size);
385 rc = llapi_layout_pattern_get(layout, &pattern);
386 ASSERTF(rc == 0, "errno = %d\n", errno);
387 ASSERTF(pattern == LLAPI_LAYOUT_DEFAULT, "pattern = %"PRIu64"\n",
390 llapi_layout_free(layout);
393 /* Verify llapi_layout_patter_set() return values for various inputs. */
394 #define T9_DESC "verify llapi_layout_pattern_set() return values"
397 struct llapi_layout *layout;
400 layout = llapi_layout_alloc();
401 ASSERTF(layout != NULL, "errno = %d\n", errno);
404 rc = llapi_layout_pattern_set(layout, LLAPI_LAYOUT_INVALID);
405 ASSERTF(rc == -1 && errno == EOPNOTSUPP, "rc = %d, errno = %d", rc,
409 rc = llapi_layout_pattern_set(NULL, LLAPI_LAYOUT_DEFAULT);
410 ASSERTF(rc == -1 && errno == EINVAL, "rc = %d, errno = %d", rc,
414 rc = llapi_layout_pattern_set(layout, LLAPI_LAYOUT_DEFAULT);
415 ASSERTF(rc == 0, "rc = %d, errno = %d", rc, errno);
418 rc = llapi_layout_pattern_set(layout, LLAPI_LAYOUT_RAID0);
419 ASSERTF(rc == 0, "rc = %d, errno = %d", rc, errno);
421 llapi_layout_free(layout);
424 /* Verify stripe_count interfaces return errors as expected */
425 #define T10_DESC "stripe_count error handling"
430 struct llapi_layout *layout;
432 layout = llapi_layout_alloc();
433 ASSERTF(layout != NULL, "errno = %d", errno);
435 /* invalid stripe count */
437 rc = llapi_layout_stripe_count_set(layout, LLAPI_LAYOUT_INVALID);
438 ASSERTF(rc == -1 && errno == EINVAL, "rc = %d, errno = %d", rc, errno);
441 rc = llapi_layout_stripe_count_set(layout, -1);
442 ASSERTF(rc == -1 && errno == EINVAL, "rc = %d, errno = %d", rc, errno);
446 rc = llapi_layout_stripe_count_set(NULL, 2);
447 ASSERTF(rc == -1 && errno == EINVAL, "rc = %d, errno = %d", rc, errno);
451 rc = llapi_layout_stripe_count_get(NULL, &count);
452 ASSERTF(rc == -1 && errno == EINVAL, "rc = %d, errno = %d", rc, errno);
456 rc = llapi_layout_stripe_count_get(layout, NULL);
457 ASSERTF(rc == -1 && errno == EINVAL, "rc = %d, errno = %d", rc, errno);
459 /* stripe count too large */
461 rc = llapi_layout_stripe_count_set(layout, LOV_MAX_STRIPE_COUNT + 1);
462 ASSERTF(rc == -1 && errno == EINVAL, "rc = %d, errno = %d", rc, errno);
463 llapi_layout_free(layout);
466 /* Verify stripe_size interfaces return errors as expected */
467 #define T11_DESC "stripe_size error handling"
472 struct llapi_layout *layout;
474 layout = llapi_layout_alloc();
475 ASSERTF(layout != NULL, "errno = %d", errno);
477 /* negative stripe size */
479 rc = llapi_layout_stripe_size_set(layout, -1);
480 ASSERTF(rc == -1 && errno == EINVAL, "rc = %d, errno = %d", rc, errno);
482 /* invalid stripe size */
484 rc = llapi_layout_stripe_size_set(layout, LLAPI_LAYOUT_INVALID);
485 ASSERTF(rc == -1 && errno == EINVAL, "rc = %d, errno = %d", rc, errno);
487 /* stripe size too big */
489 rc = llapi_layout_stripe_size_set(layout, (1ULL << 33));
490 ASSERTF(rc == -1 && errno == EINVAL, "rc = %d, errno = %d", rc, errno);
494 rc = llapi_layout_stripe_size_set(NULL, 1048576);
495 ASSERTF(rc == -1 && errno == EINVAL, "rc = %d, errno = %d", rc, errno);
498 rc = llapi_layout_stripe_size_get(NULL, &size);
499 ASSERTF(rc == -1 && errno == EINVAL, "rc = %d, errno = %d", rc, errno);
503 rc = llapi_layout_stripe_size_get(layout, NULL);
504 ASSERTF(rc == -1 && errno == EINVAL, "rc = %d, errno = %d", rc, errno);
506 llapi_layout_free(layout);
509 /* Verify pool_name interfaces return errors as expected */
510 #define T12_DESC "pool_name error handling"
514 struct llapi_layout *layout;
515 char mypool[LOV_MAXPOOLNAME + 1] = { '\0' };
517 layout = llapi_layout_alloc();
518 ASSERTF(layout != NULL, "errno = %d", errno);
522 rc = llapi_layout_pool_name_set(NULL, "foo");
523 ASSERTF(rc == -1 && errno == EINVAL, "rc = %d, errno = %d", rc, errno);
527 rc = llapi_layout_pool_name_set(layout, NULL);
528 ASSERTF(rc == -1 && errno == EINVAL, "rc = %d, errno = %d", rc, errno);
532 rc = llapi_layout_pool_name_get(NULL, mypool, sizeof(mypool));
533 ASSERTF(errno == EINVAL, "poolname = %s, errno = %d", poolname, errno);
537 rc = llapi_layout_pool_name_get(layout, NULL, sizeof(mypool));
538 ASSERTF(errno == EINVAL, "poolname = %s, errno = %d", poolname, errno);
540 /* Pool name too long*/
542 rc = llapi_layout_pool_name_set(layout, "0123456789abcdef");
543 ASSERTF(rc == -1 && errno == EINVAL, "rc = %d, errno = %d", rc, errno);
545 llapi_layout_free(layout);
548 /* Verify ost_index interface returns errors as expected */
549 #define T13FILE "t13"
550 #define T13_STRIPE_COUNT 2
551 #define T13_DESC "ost_index error handling"
557 struct llapi_layout *layout;
560 snprintf(path, sizeof(path), "%s/%s", lustre_dir, T13FILE);
562 layout = llapi_layout_alloc();
563 ASSERTF(layout != NULL, "errno = %d", errno);
565 /* invalid OST index */
567 rc = llapi_layout_ost_index_set(layout, 0, LLAPI_LAYOUT_INVALID);
568 ASSERTF(rc == -1 && errno == EINVAL, "rc = %d, errno = %d", rc, errno);
571 rc = llapi_layout_ost_index_set(layout, 0, -1);
572 ASSERTF(rc == -1 && errno == EINVAL, "rc = %d, errno = %d", rc, errno);
576 rc = llapi_layout_ost_index_set(NULL, 0, 1);
577 ASSERTF(rc == -1 && errno == EINVAL, "rc = %d, errno = %d", rc, errno);
580 rc = llapi_layout_ost_index_get(NULL, 0, &idx);
581 ASSERTF(rc == -1 && errno == EINVAL, "rc = %d, errno = %d", rc, errno);
585 rc = llapi_layout_ost_index_get(layout, 0, NULL);
586 ASSERTF(rc == -1 && errno == EINVAL, "rc = %d, errno = %d", rc, errno);
588 /* Layout not read from file so has no OST data. */
590 rc = llapi_layout_stripe_count_set(layout, T13_STRIPE_COUNT);
591 ASSERTF(rc == 0, "errno = %d", errno);
592 rc = llapi_layout_ost_index_get(layout, 0, &idx);
593 ASSERTF(rc == -1 && errno == EINVAL, "rc = %d, errno = %d", rc, errno);
595 /* n greater than stripe count*/
597 ASSERTF(rc >= 0 || errno == ENOENT, "errno = %d", errno);
598 rc = llapi_layout_stripe_count_set(layout, T13_STRIPE_COUNT);
599 ASSERTF(rc == 0, "errno = %d", errno);
600 fd = llapi_layout_file_create(path, 0, 0644, layout);
601 ASSERTF(fd >= 0, "errno = %d", errno);
603 ASSERTF(rc == 0, "errno = %d", errno);
604 llapi_layout_free(layout);
606 layout = llapi_layout_get_by_path(path, 0);
607 ASSERTF(layout != NULL, "errno = %d", errno);
609 rc = llapi_layout_ost_index_get(layout, T13_STRIPE_COUNT + 1, &idx);
610 ASSERTF(rc == -1 && errno == EINVAL, "rc = %d, errno = %d", rc, errno);
612 llapi_layout_free(layout);
615 /* Verify llapi_layout_file_create() returns errors as expected */
616 #define T14_DESC "llapi_layout_file_create error handling"
620 struct llapi_layout *layout = llapi_layout_alloc();
624 rc = llapi_layout_file_create(NULL, 0, 0, layout);
625 ASSERTF(rc == -1 && errno == EINVAL, "rc = %d, errno = %d", rc, errno);
627 llapi_layout_free(layout);
630 /* Can't change striping attributes of existing file. */
631 #define T15FILE "t15"
632 #define T15_STRIPE_COUNT 2
633 #define T15_DESC "Can't change striping attributes of existing file"
639 struct llapi_layout *layout;
642 snprintf(path, sizeof(path), "%s/%s", lustre_dir, T15FILE);
645 ASSERTF(rc >= 0 || errno == ENOENT, "errno = %d", errno);
647 layout = llapi_layout_alloc();
648 ASSERTF(layout != NULL, "errno = %d", errno);
649 rc = llapi_layout_stripe_count_set(layout, T15_STRIPE_COUNT);
650 ASSERTF(rc == 0, "errno = %d", errno);
653 fd = llapi_layout_file_create(path, 0, 0640, layout);
654 ASSERTF(fd >= 0, "fd = %d, errno = %d", fd, errno);
656 ASSERTF(rc == 0, "errno = %d", errno);
658 rc = llapi_layout_stripe_count_set(layout, T15_STRIPE_COUNT - 1);
660 fd = llapi_layout_file_open(path, 0, 0640, layout);
661 ASSERTF(fd >= 0, "fd = %d, errno = %d", fd, errno);
663 ASSERTF(rc == 0, "errno = %d", errno);
664 llapi_layout_free(layout);
666 layout = llapi_layout_get_by_path(path, 0);
667 ASSERTF(layout != NULL, "errno = %d", errno);
668 rc = llapi_layout_stripe_count_get(layout, &count);
669 ASSERTF(rc == 0 && count == T15_STRIPE_COUNT,
670 "rc = %d, %"PRIu64" != %d", rc, count, T15_STRIPE_COUNT);
671 llapi_layout_free(layout);
674 /* Default stripe attributes are applied as expected. */
675 #define T16FILE "t16"
676 #define T16_DESC "Default stripe attributes are applied as expected"
681 struct llapi_layout *deflayout;
682 struct llapi_layout *filelayout;
689 snprintf(path, sizeof(path), "%s/%s", lustre_dir, T16FILE);
692 ASSERTF(rc == 0 || errno == ENOENT, "errno = %d", errno);
694 deflayout = llapi_layout_get_by_path(lustre_dir, LAYOUT_GET_EXPECTED);
695 ASSERTF(deflayout != NULL, "errno = %d", errno);
696 rc = llapi_layout_stripe_size_get(deflayout, &dsize);
697 ASSERTF(rc == 0, "errno = %d", errno);
698 rc = llapi_layout_stripe_count_get(deflayout, &dcount);
699 ASSERTF(rc == 0, "errno = %d", errno);
701 /* First, with a default struct llapi_layout */
702 filelayout = llapi_layout_alloc();
703 ASSERTF(filelayout != NULL, "errno = %d", errno);
705 fd = llapi_layout_file_create(path, 0, 0640, filelayout);
706 ASSERTF(fd >= 0, "errno = %d", errno);
709 ASSERTF(rc == 0, "errno = %d", errno);
711 llapi_layout_free(filelayout);
713 filelayout = llapi_layout_get_by_path(path, 0);
714 ASSERTF(filelayout != NULL, "errno = %d", errno);
716 rc = llapi_layout_stripe_count_get(filelayout, &fcount);
717 ASSERTF(rc == 0, "errno = %d", errno);
718 ASSERTF(fcount == dcount || dcount == LLAPI_LAYOUT_DEFAULT ||
719 dcount == LLAPI_LAYOUT_WIDE,
720 "%"PRIu64" != %"PRIu64, fcount, dcount);
722 rc = llapi_layout_stripe_size_get(filelayout, &fsize);
723 ASSERTF(rc == 0, "errno = %d", errno);
724 ASSERTF(fsize == dsize, "%"PRIu64" != %"PRIu64, fsize, dsize);
726 /* NULL layout also implies default layout */
728 ASSERTF(rc == 0 || errno == ENOENT, "errno = %d", errno);
730 fd = llapi_layout_file_create(path, 0, 0640, filelayout);
731 ASSERTF(fd >= 0, "errno = %d", errno);
733 ASSERTF(rc == 0, "errno = %d", errno);
734 filelayout = llapi_layout_get_by_path(path, 0);
735 ASSERTF(filelayout != NULL, "errno = %d", errno);
737 rc = llapi_layout_stripe_count_get(filelayout, &fcount);
738 ASSERTF(rc == 0, "errno = %d", errno);
739 rc = llapi_layout_stripe_size_get(filelayout, &fsize);
740 ASSERTF(rc == 0, "errno = %d", errno);
741 ASSERTF(fcount == dcount || dcount == LLAPI_LAYOUT_DEFAULT ||
742 dcount == LLAPI_LAYOUT_WIDE,
743 "%"PRIu64" != %"PRIu64, fcount, dcount);
744 ASSERTF(fsize == dsize, "%"PRIu64" != %"PRIu64, fsize, dsize);
746 llapi_layout_free(filelayout);
747 llapi_layout_free(deflayout);
750 /* Setting stripe count to LLAPI_LAYOUT_WIDE uses all available OSTs. */
751 #define T17FILE "t17"
752 #define T17_DESC "LLAPI_LAYOUT_WIDE is honored"
758 uint64_t osts_layout;
759 struct llapi_layout *layout;
762 snprintf(path, sizeof(path), "%s/%s", lustre_dir, T17FILE);
765 ASSERTF(rc == 0 || errno == ENOENT, "errno = %d", errno);
766 layout = llapi_layout_alloc();
767 ASSERTF(layout != NULL, "errno = %d", errno);
768 rc = llapi_layout_stripe_count_set(layout, LLAPI_LAYOUT_WIDE);
769 ASSERTF(rc == 0, "errno = %d", errno);
770 fd = llapi_layout_file_create(path, 0, 0640, layout);
771 ASSERTF(fd >= 0, "errno = %d", errno);
773 ASSERTF(rc == 0, "errno = %d", errno);
774 llapi_layout_free(layout);
776 /* Get number of available OSTs */
777 fd = open(path, O_RDONLY);
778 ASSERTF(fd >= 0, "errno = %d", errno);
779 rc = llapi_lov_get_uuids(fd, NULL, &osts_all);
780 ASSERTF(rc == 0, "rc = %d, errno = %d", rc, errno);
782 ASSERTF(rc == 0, "errno = %d", errno);
784 layout = llapi_layout_get_by_path(path, 0);
785 ASSERTF(layout != NULL, "errno = %d", errno);
786 rc = llapi_layout_stripe_count_get(layout, &osts_layout);
787 ASSERTF(osts_layout == osts_all, "%"PRIu64" != %d", osts_layout,
790 llapi_layout_free(layout);
793 /* Setting pool with "fsname.pool" notation. */
794 #define T18FILE "t18"
795 #define T18_DESC "Setting pool with fsname.pool notation"
800 struct llapi_layout *layout = llapi_layout_alloc();
802 char pool[LOV_MAXPOOLNAME*2 + 1];
803 char mypool[LOV_MAXPOOLNAME + 1] = { '\0' };
805 snprintf(pool, sizeof(pool), "lustre.%s", poolname);
807 snprintf(path, sizeof(path), "%s/%s", lustre_dir, T18FILE);
809 ASSERTF(layout != NULL, "errno = %d", errno);
812 ASSERTF(rc == 0 || errno == ENOENT, "errno = %d", errno);
814 rc = llapi_layout_pool_name_set(layout, pool);
815 ASSERTF(rc == 0, "errno = %d", errno);
817 rc = llapi_layout_pool_name_get(layout, mypool, sizeof(mypool));
818 ASSERTF(rc == 0, "errno = %d", errno);
819 rc = strcmp(mypool, poolname);
820 ASSERTF(rc == 0, "%s != %s", mypool, poolname);
821 fd = llapi_layout_file_create(path, 0, 0640, layout);
822 ASSERTF(fd >= 0, "errno = %d", errno);
824 ASSERTF(rc == 0, "errno = %d", errno);
826 llapi_layout_free(layout);
828 layout = llapi_layout_get_by_path(path, 0);
829 ASSERTF(layout != NULL, "errno = %d", errno);
830 rc = llapi_layout_pool_name_get(layout, mypool, sizeof(mypool));
831 ASSERTF(rc == 0, "errno = %d", errno);
832 rc = strcmp(mypool, poolname);
833 ASSERTF(rc == 0, "%s != %s", mypool, poolname);
834 llapi_layout_free(layout);
837 #define T19_DESC "Maximum length pool name is NULL-terminated"
840 struct llapi_layout *layout;
841 char *name = "0123456789abcde";
842 char mypool[LOV_MAXPOOLNAME + 1] = { '\0' };
845 layout = llapi_layout_alloc();
846 ASSERTF(layout != NULL, "errno = %d", errno);
847 rc = llapi_layout_pool_name_set(layout, name);
848 ASSERTF(rc == 0, "errno = %d", errno);
849 rc = llapi_layout_pool_name_get(layout, mypool, sizeof(mypool));
850 ASSERTF(strlen(name) == strlen(mypool), "name = %s, str = %s", name,
852 llapi_layout_free(layout);
855 #define T20FILE "t20"
856 #define T20_DESC "LLAPI_LAYOUT_DEFAULT is honored"
861 struct llapi_layout *deflayout;
862 struct llapi_layout *filelayout;
869 snprintf(path, sizeof(path), "%s/%s", lustre_dir, T20FILE);
872 ASSERTF(rc == 0 || errno == ENOENT, "errno = %d", errno);
874 filelayout = llapi_layout_alloc();
875 ASSERTF(filelayout != NULL, "errno = %d", errno);
877 rc = llapi_layout_stripe_size_set(filelayout, LLAPI_LAYOUT_DEFAULT);
878 ASSERTF(rc == 0, "rc = %d, errno = %d", rc, errno);
880 rc = llapi_layout_stripe_count_set(filelayout, LLAPI_LAYOUT_DEFAULT);
881 ASSERTF(rc == 0, "rc = %d, errno = %d", rc, errno);
883 fd = llapi_layout_file_create(path, 0, 0640, filelayout);
884 ASSERTF(fd >= 0, "errno = %d", errno);
887 ASSERTF(rc == 0, "errno = %d", errno);
889 llapi_layout_free(filelayout);
891 deflayout = llapi_layout_get_by_path(lustre_dir, LAYOUT_GET_EXPECTED);
892 ASSERTF(deflayout != NULL, "errno = %d", errno);
894 filelayout = llapi_layout_get_by_path(path, 0);
895 ASSERTF(filelayout != NULL, "errno = %d", errno);
897 rc = llapi_layout_stripe_count_get(filelayout, &fcount);
898 ASSERTF(rc == 0, "errno = %d", errno);
899 rc = llapi_layout_stripe_count_get(deflayout, &dcount);
900 ASSERTF(rc == 0, "errno = %d", errno);
901 ASSERTF(fcount == dcount || dcount == LLAPI_LAYOUT_DEFAULT ||
902 dcount == LLAPI_LAYOUT_WIDE,
903 "%"PRIu64" != %"PRIu64, fcount, dcount);
905 rc = llapi_layout_stripe_size_get(filelayout, &fsize);
906 ASSERTF(rc == 0, "errno = %d", errno);
907 rc = llapi_layout_stripe_size_get(deflayout, &dsize);
908 ASSERTF(rc == 0, "errno = %d", errno);
909 ASSERTF(fsize == dsize, "%"PRIu64" != %"PRIu64, fsize, dsize);
911 llapi_layout_free(filelayout);
912 llapi_layout_free(deflayout);
915 #define T21_DESC "llapi_layout_file_create fails for non-Lustre file"
918 struct llapi_layout *layout;
919 char template[PATH_MAX];
923 snprintf(template, sizeof(template), "%s/XXXXXX", P_tmpdir);
924 fd = mkstemp(template);
925 ASSERTF(fd >= 0, "template = %s, errno = %d", template, errno);
927 ASSERTF(rc == 0, "errno = %d", fd);
928 rc = unlink(template);
929 ASSERTF(rc == 0, "errno = %d", errno);
931 layout = llapi_layout_alloc();
932 ASSERTF(layout != NULL, "errno = %d", errno);
934 fd = llapi_layout_file_create(template, 0, 0640, layout);
935 ASSERTF(fd == -1 && errno == ENOTTY,
936 "fd = %d, errno = %d, template = %s", fd, errno, template);
937 llapi_layout_free(layout);
940 #define T22FILE "t22"
941 #define T22_DESC "llapi_layout_file_create applied mode correctly"
948 mode_t mode_in = 0640;
952 snprintf(path, sizeof(path), "%s/%s", lustre_dir, T22FILE);
955 ASSERTF(rc == 0 || errno == ENOENT, "errno = %d", errno);
957 umask_orig = umask(S_IWGRP | S_IWOTH);
959 fd = llapi_layout_file_create(path, 0, mode_in, NULL);
960 ASSERTF(fd >= 0, "errno = %d", errno);
962 (void) umask(umask_orig);
965 ASSERTF(rc == 0, "errno = %d", errno);
968 ASSERTF(rc == 0, "errno = %d", fd);
970 mode_out = st.st_mode & ~S_IFMT;
971 ASSERTF(mode_in == mode_out, "%o != %o", mode_in, mode_out);
974 #define T23_DESC "llapi_layout_get_by_path fails for non-Lustre file"
977 struct llapi_layout *layout;
978 char template[PATH_MAX];
982 snprintf(template, sizeof(template), "%s/XXXXXX", P_tmpdir);
983 fd = mkstemp(template);
984 ASSERTF(fd >= 0, "template = %s, errno = %d", template, errno);
986 ASSERTF(rc == 0, "errno = %d", fd);
988 layout = llapi_layout_get_by_path(template, 0);
989 ASSERTF(layout == NULL && errno == ENOTTY,
990 "errno = %d, template = %s", errno, template);
992 rc = unlink(template);
993 ASSERTF(rc == 0, "errno = %d", errno);
996 /* llapi_layout_get_by_path(path, LAYOUT_GET_EXPECTED) returns expected layout
997 * for file with unspecified layout. */
998 #define T24FILE "t24"
999 #define T24_DESC "LAYOUT_GET_EXPECTED works with existing file"
1004 struct llapi_layout *layout;
1008 char path[PATH_MAX];
1010 snprintf(path, sizeof(path), "%s/%s", lustre_dir, T24FILE);
1013 ASSERTF(rc >= 0 || errno == ENOENT, "errno = %d", errno);
1014 fd = open(path, O_CREAT, 0640);
1015 ASSERTF(fd >= 0, "errno = %d", errno);
1017 ASSERTF(rc == 0, "errno = %d", errno);
1019 layout = llapi_layout_get_by_path(path, LAYOUT_GET_EXPECTED);
1020 ASSERTF(layout != NULL, "errno = %d\n", errno);
1022 rc = llapi_layout_stripe_count_get(layout, &count);
1023 ASSERTF(rc == 0, "errno = %d\n", errno);
1024 ASSERTF(count != LLAPI_LAYOUT_DEFAULT, "expected literal value");
1026 rc = llapi_layout_stripe_size_get(layout, &size);
1027 ASSERTF(rc == 0, "errno = %d\n", errno);
1028 ASSERTF(size != LLAPI_LAYOUT_DEFAULT, "expected literal value");
1030 rc = llapi_layout_pattern_get(layout, &pattern);
1031 ASSERTF(rc == 0, "errno = %d\n", errno);
1032 ASSERTF(pattern != LLAPI_LAYOUT_DEFAULT, "expected literal value");
1034 llapi_layout_free(layout);
1037 /* llapi_layout_get_by_path(path, LAYOUT_GET_EXPECTED) returns expected layout
1038 * for directory with unspecified layout. */
1039 #define T25DIR "d25"
1040 #define T25_DESC "LAYOUT_GET_EXPECTED works with directory"
1044 struct llapi_layout *layout;
1050 snprintf(dir, sizeof(dir), "%s/%s", lustre_dir, T25DIR);
1053 ASSERTF(rc >= 0 || errno == ENOENT, "errno = %d", errno);
1054 rc = mkdir(dir, 0750);
1055 ASSERTF(rc == 0, "errno = %d", errno);
1057 layout = llapi_layout_get_by_path(dir, LAYOUT_GET_EXPECTED);
1058 ASSERTF(layout != NULL, "errno = %d\n", errno);
1060 rc = llapi_layout_stripe_count_get(layout, &count);
1061 ASSERTF(rc == 0, "errno = %d\n", errno);
1062 ASSERTF(count != LLAPI_LAYOUT_DEFAULT, "expected literal value");
1064 rc = llapi_layout_stripe_size_get(layout, &size);
1065 ASSERTF(rc == 0, "errno = %d\n", errno);
1066 ASSERTF(size != LLAPI_LAYOUT_DEFAULT, "expected literal value");
1068 rc = llapi_layout_pattern_get(layout, &pattern);
1069 ASSERTF(rc == 0, "errno = %d\n", errno);
1070 ASSERTF(pattern != LLAPI_LAYOUT_DEFAULT, "expected literal value");
1072 llapi_layout_free(layout);
1075 /* llapi_layout_get_by_path(path, LAYOUT_GET_EXPECTED) correctly combines
1076 * specified attributes of parent directory with attributes filesystem root. */
1077 #define T26DIR "d26"
1078 #define T26_DESC "LAYOUT_GET_EXPECTED partially specified parent"
1079 #define T26_STRIPE_SIZE (1048576 * 4)
1083 struct llapi_layout *layout;
1084 const char *lfs = getenv("LFS");
1089 char cmd[PATH_MAX + 64];
1091 snprintf(dir, sizeof(dir), "%s/%s", lustre_dir, T26DIR);
1093 ASSERTF(rc >= 0 || errno == ENOENT, "errno = %d", errno);
1094 rc = mkdir(dir, 0750);
1095 ASSERTF(rc == 0, "errno = %d", errno);
1098 lfs = "/usr/bin/lfs";
1100 snprintf(cmd, sizeof(cmd), "%s setstripe -S %d %s", lfs,
1101 T26_STRIPE_SIZE, dir);
1103 ASSERTF(rc == 0, "system(%s): exit status %d", cmd, WEXITSTATUS(rc));
1105 layout = llapi_layout_get_by_path(dir, LAYOUT_GET_EXPECTED);
1106 ASSERTF(layout != NULL, "errno = %d\n", errno);
1108 rc = llapi_layout_stripe_count_get(layout, &count);
1109 ASSERTF(rc == 0, "errno = %d\n", errno);
1110 ASSERTF(count != LLAPI_LAYOUT_DEFAULT, "expected literal value");
1112 rc = llapi_layout_stripe_size_get(layout, &size);
1113 ASSERTF(rc == 0, "errno = %d\n", errno);
1114 ASSERTF(size == T26_STRIPE_SIZE, "size = %"PRIu64, size);
1116 rc = llapi_layout_pattern_get(layout, &pattern);
1117 ASSERTF(rc == 0, "errno = %d\n", errno);
1118 ASSERTF(pattern != LLAPI_LAYOUT_DEFAULT, "expected literal value");
1120 llapi_layout_free(layout);
1123 /* llapi_layout_get_by_path(path, LAYOUT_GET_EXPECTED) work with
1124 * non existing file. */
1125 #define T27DIR "d27"
1126 #define T27_DESC "LAYOUT_GET_EXPECTED with non existing file"
1127 #define T27_STRIPE_SIZE (1048576 * 3)
1131 struct llapi_layout *layout;
1132 const char *lfs = getenv("LFS");
1136 char dirpath[PATH_MAX + 128];
1137 char filepath[PATH_MAX * 2];
1138 char cmd[PATH_MAX * 2];
1140 snprintf(dirpath, sizeof(dirpath) - 1, "%s/%s", lustre_dir, T27DIR);
1141 snprintf(filepath, sizeof(filepath), "%s/nonesuch", dirpath);
1143 rc = rmdir(dirpath);
1144 ASSERTF(rc >= 0 || errno == ENOENT, "errno = %d", errno);
1145 rc = mkdir(dirpath, 0750);
1146 ASSERTF(rc == 0, "errno = %d", errno);
1149 lfs = "/usr/bin/lfs";
1151 snprintf(cmd, sizeof(cmd), "%s setstripe -S %d %s", lfs,
1152 T27_STRIPE_SIZE, dirpath);
1154 ASSERTF(rc == 0, "system(%s): exit status %d", cmd, WEXITSTATUS(rc));
1156 layout = llapi_layout_get_by_path(filepath, LAYOUT_GET_EXPECTED);
1157 ASSERTF(layout != NULL, "errno = %d\n", errno);
1159 rc = llapi_layout_stripe_count_get(layout, &count);
1160 ASSERTF(rc == 0, "errno = %d\n", errno);
1161 ASSERTF(count != LLAPI_LAYOUT_DEFAULT, "expected literal value");
1163 rc = llapi_layout_stripe_size_get(layout, &size);
1164 ASSERTF(rc == 0, "errno = %d\n", errno);
1165 ASSERTF(size == T27_STRIPE_SIZE, "size = %"PRIu64, size);
1167 rc = llapi_layout_pattern_get(layout, &pattern);
1168 ASSERTF(rc == 0, "errno = %d\n", errno);
1169 ASSERTF(pattern != LLAPI_LAYOUT_DEFAULT, "expected literal value");
1171 llapi_layout_free(layout);
1174 /* llapi_layout_stripe_count_get returns LLAPI_LAYOUT_WIDE for a directory
1175 * with a stripe_count of -1. */
1176 #define T28DIR "d28"
1177 #define T28_DESC "LLAPI_LAYOUT_WIDE returned as expected"
1181 struct llapi_layout *layout;
1182 const char *lfs = getenv("LFS");
1184 char dirpath[PATH_MAX];
1185 char cmd[PATH_MAX + 64];
1187 snprintf(dirpath, sizeof(dirpath), "%s/%s", lustre_dir, T28DIR);
1189 rc = rmdir(dirpath);
1190 ASSERTF(rc >= 0 || errno == ENOENT, "errno = %d", errno);
1191 rc = mkdir(dirpath, 0750);
1192 ASSERTF(rc == 0, "errno = %d", errno);
1195 lfs = "/usr/bin/lfs";
1197 snprintf(cmd, sizeof(cmd), "%s setstripe -c -1 %s", lfs, dirpath);
1199 ASSERTF(rc == 0, "system(%s): exit status %d", cmd, WEXITSTATUS(rc));
1201 layout = llapi_layout_get_by_path(dirpath, 0);
1202 ASSERTF(layout != NULL, "errno = %d\n", errno);
1204 rc = llapi_layout_stripe_count_get(layout, &count);
1205 ASSERTF(rc == 0, "errno = %d\n", errno);
1206 ASSERTF(count == LLAPI_LAYOUT_WIDE, "count = %"PRIu64"\n", count);
1208 llapi_layout_free(layout);
1211 #define T29FILE "f29"
1212 #define T29_DESC "set ost index to non-zero stripe number"
1216 uint64_t ost0, ost1, nost;
1217 struct llapi_layout *layout;
1218 char path[PATH_MAX];
1223 layout = llapi_layout_alloc();
1224 ASSERTF(layout != NULL, "errno %d", errno);
1226 snprintf(path, sizeof(path), "%s/%s", lustre_dir, T29FILE);
1229 ASSERTF(rc >= 0 || errno == ENOENT, "errno = %d", errno);
1231 /* set ost index to LLAPI_LAYOUT_IDX_MAX should fail */
1232 rc = llapi_layout_ost_index_set(layout, 1, LLAPI_LAYOUT_IDX_MAX);
1233 ASSERTF(rc == -1 && errno == EINVAL, "rc = %d, errno = %d\n",
1236 /* specify ost index partially */
1237 rc = llapi_layout_ost_index_set(layout, 1, 0);
1238 ASSERTF(rc == 0, "errno = %d", errno);
1240 /* create a partially specified layout will fail */
1241 fd = llapi_layout_file_create(path, 0, 0660, layout);
1242 ASSERTF(fd == -1 && errno == EINVAL, "path = %s, fd = %d, errno = %d",
1246 ASSERTF(rc >= 0 || errno == ENOENT, "errno = %d", errno);
1248 /* specify all stripes */
1249 rc = llapi_layout_ost_index_set(layout, 0, 1);
1250 ASSERTF(rc == 0, "errno = %d", errno);
1253 fd = llapi_layout_file_create(path, 0, 0660, layout);
1254 ASSERTF(fd >= 0, "path = %s, fd = %d, errno = %d", path, fd, errno);
1257 ASSERTF(rc == 0, "errno = %d", errno);
1258 llapi_layout_free(layout);
1260 /* get layout from file */
1261 layout = llapi_layout_get_by_path(path, 0);
1262 ASSERTF(layout != NULL, "errno = %d", errno);
1264 rc = llapi_layout_ost_index_get(layout, 0, &ost0);
1265 ASSERTF(rc == 0, "errno = %d", errno);
1266 rc = llapi_layout_ost_index_get(layout, 1, &ost1);
1267 ASSERTF(rc == 0, "errno = %d", errno);
1268 ASSERTF(ost0 == 1, "%"PRIu64" != %d", ost0, 1);
1269 ASSERTF(ost1 == 0, "%"PRIu64" != %d", ost1, 0);
1270 llapi_layout_free(layout);
1272 /* specify more ost indexes to test realloc */
1274 layout = llapi_layout_alloc();
1275 ASSERTF(layout != NULL, "errno %d", errno);
1276 for (i = 0; i < LOV_MAX_STRIPE_COUNT; i++) {
1277 rc = llapi_layout_ost_index_set(layout, i, nost);
1278 ASSERTF(rc == 0, "errno = %d", errno);
1279 rc = llapi_layout_ost_index_get(layout, i, &ost0);
1280 ASSERTF(rc == 0, "errno = %d", errno);
1282 if (nost == num_osts)
1287 for (i = 0; i < LOV_MAX_STRIPE_COUNT; i++) {
1288 rc = llapi_layout_ost_index_get(layout, i, &ost0);
1289 ASSERTF(rc == 0, "errno = %d", errno);
1290 ASSERTF(ost0 == nost, "ost=%"PRIu64" nost=%"PRIu64"",
1293 if (nost == num_osts)
1296 llapi_layout_free(layout);
1299 layout = llapi_layout_alloc();
1300 ASSERTF(layout != NULL, "errno %d", errno);
1301 for (i = LOV_MAX_STRIPE_COUNT-1; i >= 0; i--) {
1302 rc = llapi_layout_ost_index_set(layout, i, nost);
1303 ASSERTF(rc == 0, "errno = %d", errno);
1304 rc = llapi_layout_ost_index_get(layout, i, &ost0);
1305 ASSERTF(rc == 0, "errno = %d", errno);
1307 if (nost == num_osts)
1312 for (i = LOV_MAX_STRIPE_COUNT-1; i <= 0; i--) {
1313 rc = llapi_layout_ost_index_get(layout, i, &ost0);
1314 ASSERTF(rc == 0, "errno = %d", errno);
1315 ASSERTF(ost0 == nost, "ost=%"PRIu64", nost=%"PRIu64"",
1318 if (nost == num_osts)
1321 llapi_layout_free(layout);
1324 #define T30FILE "f30"
1325 #define T30_DESC "create composite file, traverse components"
1329 uint64_t start[3], end[3];
1331 struct llapi_layout *layout;
1332 char path[PATH_MAX];
1335 end[0] = 64 * 1024 * 1024; /* 64m */
1337 end[1] = 1 * 1024 * 1024 * 1024; /* 1G */
1339 end[2] = LUSTRE_EOF;
1344 snprintf(path, sizeof(path), "%s/%s", lustre_dir, T30FILE);
1347 ASSERTF(rc >= 0 || errno == ENOENT, "errno = %d", errno);
1349 layout = llapi_layout_alloc();
1350 ASSERTF(layout != NULL, "errno %d", errno);
1352 rc = llapi_layout_stripe_count_set(layout, 1);
1353 ASSERTF(rc == 0, "errno %d", errno);
1355 /* add component without adjusting previous component's extent
1357 rc = llapi_layout_comp_add(layout);
1358 ASSERTF(rc == -1 && errno == EINVAL, "rc %d, errno %d", rc, errno);
1360 rc = llapi_layout_comp_extent_set(layout, start[0], end[0]);
1361 ASSERTF(rc == 0, "errno %d", errno);
1363 rc = llapi_layout_comp_add(layout);
1364 ASSERTF(rc == 0, "errno %d", errno);
1366 /* set non-contiguous extent will fail */
1367 rc = llapi_layout_comp_extent_set(layout, start[1] * 2, end[1]);
1368 ASSERTF(rc == 0, "errno %d", errno);
1369 rc = llapi_layout_sanity(layout, false, false);
1370 ASSERTF(rc == 12 /*LSE_NOT_ADJACENT_PREV*/, "rc %d", rc);
1372 rc = llapi_layout_comp_extent_set(layout, start[1], end[1]);
1373 ASSERTF(rc == 0, "errno %d", errno);
1375 rc = llapi_layout_comp_add(layout);
1376 ASSERTF(rc == 0, "errno %d", errno);
1378 rc = llapi_layout_comp_extent_set(layout, start[2], end[2]);
1379 ASSERTF(rc == 0, "errno %d", errno);
1381 /* create composite file */
1382 fd = llapi_layout_file_create(path, 0, 0660, layout);
1383 ASSERTF(fd >= 0, "path = %s, fd = %d, errno = %d", path, fd, errno);
1385 llapi_layout_free(layout);
1387 /* traverse & verify all components */
1388 layout = llapi_layout_get_by_path(path, 0);
1389 ASSERTF(layout != NULL, "errno = %d", errno);
1391 /* current component should be the tail component */
1392 rc = llapi_layout_comp_extent_get(layout, &s, &e);
1393 ASSERTF(rc == 0, "errno %d", errno);
1394 ASSERTF(s == start[2] && e == end[2],
1395 "s: %"PRIu64", e: %"PRIu64"", s, e);
1397 rc = llapi_layout_comp_use(layout, LLAPI_LAYOUT_COMP_USE_FIRST);
1398 ASSERTF(rc == 0, "rc %d, errno %d", rc, errno);
1400 /* delete non-tail component will fail */
1401 rc = llapi_layout_comp_del(layout);
1402 ASSERTF(rc == -1 && errno == EINVAL, "rc %d, errno %d", rc, errno);
1404 rc = llapi_layout_comp_extent_get(layout, &s, &e);
1405 ASSERTF(rc == 0, "errno %d", errno);
1406 ASSERTF(s == start[0] && e == end[0],
1407 "s: %"PRIu64", e: %"PRIu64"", s, e);
1409 rc = llapi_layout_comp_use(layout, LLAPI_LAYOUT_COMP_USE_NEXT);
1410 ASSERTF(rc == 0, "rc %d, errno %d", rc, errno);
1412 rc = llapi_layout_comp_extent_get(layout, &s, &e);
1413 ASSERTF(rc == 0, "errno %d", errno);
1414 ASSERTF(s == start[1] && e == end[1],
1415 "s: %"PRIu64", e: %"PRIu64"", s, e);
1417 rc = llapi_layout_comp_use(layout, LLAPI_LAYOUT_COMP_USE_NEXT);
1418 ASSERTF(rc == 0, "rc %d, errno %d", rc, errno);
1420 rc = llapi_layout_comp_del(layout);
1421 ASSERTF(rc == 0, "errno %d", errno);
1423 llapi_layout_free(layout);
1426 #define T31FILE "f31"
1427 #define T31_DESC "add/delete component to/from existing file"
1431 uint64_t start[2], end[2];
1434 struct llapi_layout *layout;
1435 char path[PATH_MAX];
1438 end[0] = 64 * 1024 * 1024; /* 64m */
1440 end[1] = LUSTRE_EOF;
1445 snprintf(path, sizeof(path), "%s/%s", lustre_dir, T31FILE);
1448 ASSERTF(rc >= 0 || errno == ENOENT, "errno = %d", errno);
1450 layout = llapi_layout_alloc();
1451 ASSERTF(layout != NULL, "errno %d", errno);
1453 rc = llapi_layout_stripe_count_set(layout, 1);
1454 ASSERTF(rc == 0, "errno %d", errno);
1456 rc = llapi_layout_comp_extent_set(layout, start[0], end[0]);
1457 ASSERTF(rc == 0, "errno %d", errno);
1459 /* create composite file */
1460 fd = llapi_layout_file_create(path, 0, 0660, layout);
1461 ASSERTF(fd >= 0, "path = %s, fd = %d, errno = %d", path, fd, errno);
1462 llapi_layout_free(layout);
1464 layout = llapi_layout_alloc();
1465 ASSERTF(layout != NULL, "errno %d", errno);
1467 rc = llapi_layout_stripe_count_set(layout, 2);
1468 ASSERTF(rc == 0, "errno %d", errno);
1470 rc = llapi_layout_comp_extent_set(layout, start[1], end[1]);
1471 ASSERTF(rc == 0, "errno %d", errno);
1473 /* add comopnent to existing file */
1474 rc = llapi_layout_file_comp_add(path, layout);
1475 ASSERTF(rc == 0, "errno %d", errno);
1476 llapi_layout_free(layout);
1478 /* verify the composite layout after adding */
1479 layout = llapi_layout_get_by_path(path, 0);
1480 ASSERTF(layout != NULL, "errno = %d", errno);
1482 rc = llapi_layout_comp_use(layout, LLAPI_LAYOUT_COMP_USE_FIRST);
1483 ASSERTF(rc == 0, "rc %d, errno %d", rc, errno);
1486 rc = llapi_layout_comp_extent_get(layout, &s, &e);
1487 ASSERTF(rc == 0 && i < 2, "i %d, errno %d", i, errno);
1488 ASSERTF(s == start[i] && e == end[i],
1489 "i: %d s: %"PRIu64", e: %"PRIu64"", i, s, e);
1491 rc = llapi_layout_comp_id_get(layout, &id[i]);
1492 ASSERTF(rc == 0 && id[i] != 0, "i %d, errno %d, id %d",
1495 rc = llapi_layout_comp_use(layout, LLAPI_LAYOUT_COMP_USE_NEXT);
1496 ASSERTF(rc == 0 || i == 1, "i=%d rc=%d errno=%d", i, rc, errno);
1500 /* Verify reverse iteration gives the same IDs as forward iteration */
1501 rc = llapi_layout_comp_use(layout, LLAPI_LAYOUT_COMP_USE_LAST);
1502 ASSERTF(rc == 0, "rc %d, errno %d", rc, errno);
1507 rc = llapi_layout_comp_id_get(layout, &comp_id);
1508 ASSERTF(rc == 0 && comp_id == id[i],
1509 "i %d, errno %d, id[] %u/%u", i, errno, id[i], comp_id);
1511 rc = llapi_layout_comp_use(layout, LLAPI_LAYOUT_COMP_USE_PREV);
1512 ASSERTF(rc == 0 || i == 0, "i=%d rc=%d errno=%d", i, rc, errno);
1515 llapi_layout_free(layout);
1517 /* delete non-tail component will fail */
1518 rc = llapi_layout_file_comp_del(path, id[0], 0);
1519 ASSERTF(rc < 0 && errno == EINVAL, "rc %d, errno %d", rc, errno);
1521 rc = llapi_layout_file_comp_del(path, id[1], 0);
1522 ASSERTF(rc == 0, "rc %d, errno %d", rc, errno);
1524 /* verify the composite layout after deleting */
1525 layout = llapi_layout_get_by_path(path, 0);
1526 ASSERTF(layout != NULL, "errno = %d", errno);
1528 rc = llapi_layout_comp_use(layout, LLAPI_LAYOUT_COMP_USE_FIRST);
1529 ASSERTF(rc == 0, "rc %d, errno %d", rc, errno);
1531 rc = llapi_layout_comp_extent_get(layout, &s, &e);
1532 ASSERTF(rc == 0, "errno %d", errno);
1533 ASSERTF(s == start[0] && e == end[0],
1534 "s: %"PRIu64", e: %"PRIu64"", s, e);
1537 #define T32FILE "t32"
1538 #define T32_STRIPE_COUNT (num_osts*2)
1539 #define T32_DESC "Test overstriping with layout_file_create"
1545 struct llapi_layout *layout = llapi_layout_alloc();
1546 void *lmdbuf = NULL;
1547 struct lov_user_md *lmd;
1548 char path[PATH_MAX];
1550 ASSERTF(layout != NULL, "errno %d", errno);
1552 /* Maximum possible, to be on the safe side - num_osts could be large */
1553 lmdbuf = malloc(XATTR_SIZE_MAX);
1554 ASSERTF(lmdbuf != NULL, "errno %d", errno);
1557 snprintf(path, sizeof(path), "%s/%s", lustre_dir, T32FILE);
1560 ASSERTF(rc >= 0 || errno == ENOENT, "errno = %d", errno);
1563 rc = llapi_layout_stripe_count_set(layout, T32_STRIPE_COUNT);
1564 ASSERTF(rc == 0, "errno = %d", errno);
1565 rc = llapi_layout_stripe_count_get(layout, &count);
1566 ASSERTF(rc == 0 && count == T32_STRIPE_COUNT, "%"PRIu64" != %d", count,
1569 rc = llapi_layout_pattern_set(layout, LLAPI_LAYOUT_OVERSTRIPING);
1570 ASSERTF(rc == 0, "errno = %d", errno);
1573 fd = llapi_layout_file_create(path, 0, 0660, layout);
1574 ASSERTF(fd >= 0, "path = %s, errno = %d", path, errno);
1576 rc = ioctl(fd, LL_IOC_LOV_GETSTRIPE_NEW, lmdbuf);
1577 ASSERTF(rc == 0, "errno = %d", errno);
1579 count = lmd->lmm_stripe_count;
1580 ASSERTF(count == T32_STRIPE_COUNT,
1581 "stripe count (%"PRIu64") not equal to expected (%d)",
1582 count, T32_STRIPE_COUNT);
1585 ASSERTF(rc == 0, "errno = %d", errno);
1586 llapi_layout_free(layout);
1590 #define T33FILE "t33"
1591 #define T33_STRIPE_COUNT (num_osts*2)
1592 #define T33_DESC "Test overstriping with llapi_file_open"
1598 void *lmdbuf = NULL;
1599 struct lov_user_md *lmd;
1600 char path[PATH_MAX];
1602 /* Maximum possible, to be on the safe side - num_osts could be large */
1603 lmdbuf = malloc(XATTR_SIZE_MAX);
1604 ASSERTF(lmdbuf != NULL, "errno %d", errno);
1607 snprintf(path, sizeof(path), "%s/%s", lustre_dir, T33FILE);
1610 ASSERTF(rc >= 0 || errno == ENOENT, "errno = %d", errno);
1612 fd = llapi_file_open(path, O_CREAT | O_RDWR, 0660, 0, -1, num_osts*2,
1613 LOV_PATTERN_RAID0 | LOV_PATTERN_OVERSTRIPING);
1614 ASSERTF(fd >= 0, "path = %s, errno = %d", path, errno);
1616 rc = ioctl(fd, LL_IOC_LOV_GETSTRIPE_NEW, lmdbuf);
1617 ASSERTF(rc == 0, "errno = %d", errno);
1619 count = lmd->lmm_stripe_count;
1620 ASSERTF(count == T33_STRIPE_COUNT,
1621 "stripe count (%"PRIu64") not equal to expected (%d)",
1622 count, T33_STRIPE_COUNT);
1625 ASSERTF(rc == 0, "errno = %d", errno);
1629 #define T34FILE "f34"
1630 #define T34_DESC "create simple valid & invalid self extending layouts"
1634 uint64_t start[4], end[4];
1635 struct llapi_layout *layout;
1636 char path[PATH_MAX];
1639 end[0] = 10 * 1024 * 1024; /* 10m */
1641 end[1] = 1024 * 1024 * 1024; /* 1G */
1643 end[2] = 10ull * 1024 * 1024 * 1024; /* 10G */
1645 end[3] = LUSTRE_EOF;
1650 snprintf(path, sizeof(path), "%s/%s", lustre_dir, T34FILE);
1653 ASSERTF(rc >= 0 || errno == ENOENT, "errno = %d", errno);
1655 layout = llapi_layout_alloc();
1656 ASSERTF(layout != NULL, "errno %d", errno);
1658 rc = llapi_layout_stripe_count_set(layout, 1);
1659 ASSERTF(rc == 0, "errno %d", errno);
1661 /* add component without adjusting previous component's extent
1664 rc = llapi_layout_comp_add(layout);
1665 ASSERTF(rc == -1 && errno == EINVAL, "rc %d, errno %d", rc, errno);
1667 rc = llapi_layout_comp_extent_set(layout, start[0], end[0]);
1668 ASSERTF(rc == 0, "errno %d", errno);
1670 rc = llapi_layout_comp_add(layout);
1671 ASSERTF(rc == 0, "errno %d", errno);
1673 rc = llapi_layout_comp_extent_set(layout, start[1], end[1]);
1674 ASSERTF(rc == 0, "errno %d", errno);
1676 rc = llapi_layout_comp_flags_set(layout, LCME_FL_EXTENSION);
1677 ASSERTF(rc == 0, "errno %d", errno);
1679 /* Invalid size, too small - < 64 MiB */
1680 rc = llapi_layout_extension_size_set(layout, 32 << 20);
1681 ASSERTF(rc == -1, "errno %d", errno);
1683 /* too large - > 4 TiB */
1684 rc = llapi_layout_extension_size_set(layout, 5ull << 40);
1685 ASSERTF(rc == -1, "errno %d", errno);
1687 /* Valid size, 64 MiB */
1688 rc = llapi_layout_extension_size_set(layout, 64 << 20);
1689 ASSERTF(rc == 0, "errno %d", errno);
1691 rc = llapi_layout_comp_add(layout);
1692 ASSERTF(rc == 0, "errno %d", errno);
1694 rc = llapi_layout_comp_extent_set(layout, start[2], end[2]);
1695 ASSERTF(rc == 0, "errno %d", errno);
1697 /* Set extension space flag on adjacent components:
1698 * This is invalid, but can't be checked until we try to create the
1700 rc = llapi_layout_comp_flags_set(layout, LCME_FL_EXTENSION);
1701 ASSERTF(rc == 0, "errno %d", errno);
1703 fd = llapi_layout_file_create(path, 0, 0660, layout);
1704 ASSERTF(fd = -1, "path = %s, fd = %d, errno = %d", path, fd, errno);
1706 /* Delete incorrect component */
1707 rc = llapi_layout_comp_del(layout);
1708 ASSERTF(rc == 0, "errno %d", errno);
1710 rc = llapi_layout_comp_add(layout);
1711 ASSERTF(rc == 0, "errno %d", errno);
1713 /* Convert this comp to zero-length so it can be followed by extension
1715 rc = llapi_layout_comp_extent_set(layout, start[2], start[2]);
1716 ASSERTF(rc == 0, "errno %d", errno);
1718 rc = llapi_layout_comp_add(layout);
1719 ASSERTF(rc == 0, "errno %d", errno);
1721 rc = llapi_layout_comp_extent_set(layout, start[2], end[3]);
1722 ASSERTF(rc == 0, "errno %d", errno);
1724 rc = llapi_layout_comp_flags_set(layout, LCME_FL_EXTENSION);
1725 ASSERTF(rc == 0, "errno %d", errno);
1727 /* create composite file */
1728 fd = llapi_layout_file_create(path, 0, 0660, layout);
1729 ASSERTF(fd >= 0, "path = %s, fd = %d, errno = %d", path, fd, errno);
1731 llapi_layout_free(layout);
1733 /* traverse & verify all components */
1734 layout = llapi_layout_get_by_path(path, 0);
1735 ASSERTF(layout != NULL, "errno = %d", errno);
1737 rc = llapi_layout_sanity(layout, false, false);
1738 ASSERTF(rc == 0, "errno %d", errno);
1741 #define TEST_DESC_LEN 80
1742 struct test_tbl_entry {
1743 void (*tte_fn)(void);
1744 char tte_desc[TEST_DESC_LEN];
1748 static struct test_tbl_entry test_tbl[] = {
1749 { .tte_fn = &test0, .tte_desc = T0_DESC, .tte_skip = false },
1750 { .tte_fn = &test1, .tte_desc = T1_DESC, .tte_skip = false },
1751 { .tte_fn = &test2, .tte_desc = T2_DESC, .tte_skip = false },
1752 { .tte_fn = &test3, .tte_desc = T3_DESC, .tte_skip = false },
1753 { .tte_fn = &test4, .tte_desc = T4_DESC, .tte_skip = false },
1754 { .tte_fn = &test5, .tte_desc = T5_DESC, .tte_skip = false },
1755 { .tte_fn = &test6, .tte_desc = T6_DESC, .tte_skip = false },
1756 { .tte_fn = &test7, .tte_desc = T7_DESC, .tte_skip = false },
1757 { .tte_fn = &test8, .tte_desc = T8_DESC, .tte_skip = false },
1758 { .tte_fn = &test9, .tte_desc = T9_DESC, .tte_skip = false },
1759 { .tte_fn = &test10, .tte_desc = T10_DESC, .tte_skip = false },
1760 { .tte_fn = &test11, .tte_desc = T11_DESC, .tte_skip = false },
1761 { .tte_fn = &test12, .tte_desc = T12_DESC, .tte_skip = false },
1762 { .tte_fn = &test13, .tte_desc = T13_DESC, .tte_skip = false },
1763 { .tte_fn = &test14, .tte_desc = T14_DESC, .tte_skip = false },
1764 { .tte_fn = &test15, .tte_desc = T15_DESC, .tte_skip = false },
1765 { .tte_fn = &test16, .tte_desc = T16_DESC, .tte_skip = false },
1766 { .tte_fn = &test17, .tte_desc = T17_DESC, .tte_skip = false },
1767 { .tte_fn = &test18, .tte_desc = T18_DESC, .tte_skip = false },
1768 { .tte_fn = &test19, .tte_desc = T19_DESC, .tte_skip = false },
1769 { .tte_fn = &test20, .tte_desc = T20_DESC, .tte_skip = false },
1770 { .tte_fn = &test21, .tte_desc = T21_DESC, .tte_skip = false },
1771 { .tte_fn = &test22, .tte_desc = T22_DESC, .tte_skip = false },
1772 { .tte_fn = &test23, .tte_desc = T23_DESC, .tte_skip = false },
1773 { .tte_fn = &test24, .tte_desc = T24_DESC, .tte_skip = false },
1774 { .tte_fn = &test25, .tte_desc = T25_DESC, .tte_skip = false },
1775 { .tte_fn = &test26, .tte_desc = T26_DESC, .tte_skip = false },
1776 { .tte_fn = &test27, .tte_desc = T27_DESC, .tte_skip = false },
1777 { .tte_fn = &test28, .tte_desc = T28_DESC, .tte_skip = false },
1778 { .tte_fn = &test29, .tte_desc = T29_DESC, .tte_skip = false },
1779 { .tte_fn = &test30, .tte_desc = T30_DESC, .tte_skip = false },
1780 { .tte_fn = &test31, .tte_desc = T31_DESC, .tte_skip = false },
1781 { .tte_fn = &test32, .tte_desc = T32_DESC, .tte_skip = false },
1782 { .tte_fn = &test33, .tte_desc = T33_DESC, .tte_skip = false },
1783 { .tte_fn = &test34, .tte_desc = T34_DESC, .tte_skip = false },
1786 #define NUM_TESTS (sizeof(test_tbl) / sizeof(struct test_tbl_entry))
1788 void print_test_desc(int test_num, const char *test_desc, const char *status)
1792 printf(" test %2d: %s ", test_num, test_desc);
1793 for (i = 0; i < TEST_DESC_LEN - strlen(test_desc); i++)
1795 printf(" %s\n", status);
1798 /* This function runs a single test by forking the process. This way,
1799 * if there is a segfault during a test, the test program won't crash. */
1800 int test(void (*test_fn)(), const char *test_desc, bool test_skip, int test_num)
1804 char status_buf[128];
1807 if (!run_list_provided)
1808 print_test_desc(test_num, test_desc, "skip");
1814 ERROR("cannot fork: %s", strerror(errno));
1815 } else if (pid > 0) {
1818 /* Non-zero value indicates failure. */
1821 strncpy(status_buf, "pass", sizeof(status_buf));
1822 } else if WIFSIGNALED(status) {
1823 snprintf(status_buf, sizeof(status_buf),
1824 "fail (exit status %d, killed by SIG%d)",
1825 WEXITSTATUS(status), WTERMSIG(status));
1828 snprintf(status_buf, sizeof(status_buf),
1829 "fail (exit status %d)", WEXITSTATUS(status));
1832 print_test_desc(test_num, test_desc, status_buf);
1833 } else if (pid == 0) {
1834 /* Run the test in the child process. Exit with 0 for success,
1835 * non-zero for failure */
1843 /* 'str_tests' are the tests to be skipped, such as "1,3,4,.." */
1844 static void set_tests_skipped(char *str_tests)
1846 char *ptr = str_tests;
1849 if (ptr == NULL || strlen(ptr) == 0)
1852 while (*ptr != '\0') {
1853 tstno = strtoul(ptr, &ptr, 0);
1854 if (tstno >= 0 && tstno < NUM_TESTS)
1855 test_tbl[tstno].tte_skip = true;
1863 static void set_tests_to_run(char *str_tests)
1865 char *ptr = str_tests;
1869 if (ptr == NULL || strlen(ptr) == 0)
1872 for (i = 0; i < NUM_TESTS ; i++)
1873 test_tbl[i].tte_skip = true;
1875 while (*ptr != '\0') {
1876 tstno = strtoul(ptr, &ptr, 0);
1877 if (tstno >= 0 && tstno < NUM_TESTS)
1878 test_tbl[tstno].tte_skip = false;
1886 static void process_args(int argc, char *argv[])
1890 while ((c = getopt(argc, argv, "d:p:o:s:t:")) != -1) {
1893 lustre_dir = optarg;
1899 num_osts = atoi(optarg);
1902 set_tests_skipped(optarg);
1905 run_list_provided = true;
1906 set_tests_to_run(optarg);
1909 fprintf(stderr, "Unknown option '%c'\n", optopt);
1915 int main(int argc, char *argv[])
1922 llapi_msg_set_level(LLAPI_MSG_OFF);
1924 process_args(argc, argv);
1925 if (lustre_dir == NULL)
1926 lustre_dir = "/mnt/lustre";
1927 if (poolname == NULL)
1928 poolname = "testpool";
1933 DIE("Error: at least 2 OSTS are required\n");
1935 if (stat(lustre_dir, &s) < 0)
1936 DIE("cannot stat %s: %s\n", lustre_dir, strerror(errno));
1937 else if (!S_ISDIR(s.st_mode))
1938 DIE("%s: not a directory\n", lustre_dir);
1940 rc = llapi_search_fsname(lustre_dir, fsname);
1942 fprintf(stderr, "Error: %s: not a Lustre filesystem\n",
1947 /* Play nice with Lustre test scripts. Non-line buffered output
1948 * stream under I/O redirection may appear incorrectly. */
1949 setvbuf(stdout, NULL, _IOLBF, 0);
1951 for (i = 0; i < NUM_TESTS; i++) {
1952 struct test_tbl_entry *tst = &test_tbl[i];
1953 if (test(tst->tte_fn, tst->tte_desc, tst->tte_skip, i) != 0)