void usage(char *prog)
{
- printf("Usage: %s [-d lustre_dir] [-p pool_name] [-o num_osts]\n",
- prog);
+ printf("Usage: %s [-d lustre_dir] [-p pool_name] [-o num_osts] "
+ "[-s $n,$m,..]\n", prog);
exit(0);
}
{
int rc;
struct llapi_layout *layout;
- lustre_fid fid;
+ struct lu_fid fid;
char fidstr[4096];
char path[PATH_MAX];
rc = unlink(path);
ASSERTF(rc == 0 || errno == ENOENT, "errno = %d", errno);
- snprintf(cmd, sizeof(cmd), "%s setstripe %s %s -c %d -s %d %s", lfs,
+ snprintf(cmd, sizeof(cmd), "%s setstripe %s %s -c %d -S %d %s", lfs,
strlen(poolname) > 0 ? "-p" : "", poolname, T4_STRIPE_COUNT,
T4_STRIPE_SIZE, path);
rc = system(cmd);
layout = llapi_layout_alloc();
ASSERTF(layout != NULL, "errno = %d", errno);
- /* Only setting OST index for stripe 0 is supported for now. */
- errno = 0;
- rc = llapi_layout_ost_index_set(layout, 1, 1);
- ASSERTF(rc == -1 && errno == EOPNOTSUPP, "rc = %d, errno = %d",
- rc, errno);
-
/* invalid OST index */
errno = 0;
rc = llapi_layout_ost_index_set(layout, 0, LLAPI_LAYOUT_INVALID);
rc = llapi_layout_stripe_count_get(filelayout, &fcount);
ASSERTF(rc == 0, "errno = %d", errno);
- ASSERTF(fcount == dcount, "%"PRIu64" != %"PRIu64, fcount, dcount);
+ ASSERTF(fcount == dcount || dcount == LLAPI_LAYOUT_DEFAULT ||
+ dcount == LLAPI_LAYOUT_WIDE,
+ "%"PRIu64" != %"PRIu64, fcount, dcount);
rc = llapi_layout_stripe_size_get(filelayout, &fsize);
ASSERTF(rc == 0, "errno = %d", errno);
ASSERTF(rc == 0, "errno = %d", errno);
rc = llapi_layout_stripe_size_get(filelayout, &fsize);
ASSERTF(rc == 0, "errno = %d", errno);
- ASSERTF(fcount == dcount, "%"PRIu64" != %"PRIu64, fcount, dcount);
+ ASSERTF(fcount == dcount || dcount == LLAPI_LAYOUT_DEFAULT ||
+ dcount == LLAPI_LAYOUT_WIDE,
+ "%"PRIu64" != %"PRIu64, fcount, dcount);
ASSERTF(fsize == dsize, "%"PRIu64" != %"PRIu64, fsize, dsize);
llapi_layout_free(filelayout);
ASSERTF(rc == 0, "errno = %d", errno);
rc = llapi_layout_stripe_count_get(deflayout, &dcount);
ASSERTF(rc == 0, "errno = %d", errno);
- ASSERTF(fcount == dcount, "%"PRIu64" != %"PRIu64, fcount, dcount);
+ ASSERTF(fcount == dcount || dcount == LLAPI_LAYOUT_DEFAULT ||
+ dcount == LLAPI_LAYOUT_WIDE,
+ "%"PRIu64" != %"PRIu64, fcount, dcount);
rc = llapi_layout_stripe_size_get(filelayout, &fsize);
ASSERTF(rc == 0, "errno = %d", errno);
if (lfs == NULL)
lfs = "/usr/bin/lfs";
- snprintf(cmd, sizeof(cmd), "%s setstripe -s %d %s", lfs,
+ snprintf(cmd, sizeof(cmd), "%s setstripe -S %d %s", lfs,
T26_STRIPE_SIZE, dir);
rc = system(cmd);
ASSERTF(rc == 0, "system(%s): exit status %d", cmd, WEXITSTATUS(rc));
if (lfs == NULL)
lfs = "/usr/bin/lfs";
- snprintf(cmd, sizeof(cmd), "%s setstripe -s %d %s", lfs,
+ snprintf(cmd, sizeof(cmd), "%s setstripe -S %d %s", lfs,
T27_STRIPE_SIZE, dirpath);
rc = system(cmd);
ASSERTF(rc == 0, "system(%s): exit status %d", cmd, WEXITSTATUS(rc));
llapi_layout_free(layout);
}
+#define T29FILE "f29"
+#define T29_DESC "set ost index to non-zero stripe number"
+void test29(void)
+{
+ int rc, fd, i;
+ uint64_t ost0, ost1, nost;
+ struct llapi_layout *layout;
+ char path[PATH_MAX];
+
+ if (num_osts < 2)
+ return;
+
+ layout = llapi_layout_alloc();
+ ASSERTF(layout != NULL, "errno %d", errno);
+
+ snprintf(path, sizeof(path), "%s/%s", lustre_dir, T29FILE);
+
+ rc = unlink(path);
+ ASSERTF(rc >= 0 || errno == ENOENT, "errno = %d", errno);
+
+ /* set ost index to LLAPI_LAYOUT_IDX_MAX should fail */
+ rc = llapi_layout_ost_index_set(layout, 1, LLAPI_LAYOUT_IDX_MAX);
+ ASSERTF(rc == -1 && errno == EINVAL, "rc = %d, errno = %d\n",
+ rc, errno);
+
+ /* specify ost index partially */
+ rc = llapi_layout_ost_index_set(layout, 1, 0);
+ ASSERTF(rc == 0, "errno = %d", errno);
+
+ /* create a partially specified layout will fail */
+ fd = llapi_layout_file_create(path, 0, 0660, layout);
+ ASSERTF(fd == -1 && errno == EINVAL, "path = %s, fd = %d, errno = %d",
+ path, fd, errno);
+
+ rc = unlink(path);
+ ASSERTF(rc >= 0 || errno == ENOENT, "errno = %d", errno);
+
+ /* specify all stripes */
+ rc = llapi_layout_ost_index_set(layout, 0, 1);
+ ASSERTF(rc == 0, "errno = %d", errno);
+
+ /* create */
+ fd = llapi_layout_file_create(path, 0, 0660, layout);
+ ASSERTF(fd >= 0, "path = %s, fd = %d, errno = %d", path, fd, errno);
+
+ rc = close(fd);
+ ASSERTF(rc == 0, "errno = %d", errno);
+ llapi_layout_free(layout);
+
+ /* get layout from file */
+ layout = llapi_layout_get_by_path(path, 0);
+ ASSERTF(layout != NULL, "errno = %d", errno);
+
+ rc = llapi_layout_ost_index_get(layout, 0, &ost0);
+ ASSERTF(rc == 0, "errno = %d", errno);
+ rc = llapi_layout_ost_index_get(layout, 1, &ost1);
+ ASSERTF(rc == 0, "errno = %d", errno);
+ ASSERTF(ost0 == 1, "%"PRIu64" != %d", ost0, 1);
+ ASSERTF(ost1 == 0, "%"PRIu64" != %d", ost1, 0);
+ llapi_layout_free(layout);
+
+ /* specify more ost indexes to test realloc */
+ nost = 0;
+ layout = llapi_layout_alloc();
+ ASSERTF(layout != NULL, "errno %d", errno);
+ for (i = 0; i < LOV_MAX_STRIPE_COUNT; i++) {
+ rc = llapi_layout_ost_index_set(layout, i, nost);
+ ASSERTF(rc == 0, "errno = %d", errno);
+ rc = llapi_layout_ost_index_get(layout, i, &ost0);
+ ASSERTF(rc == 0, "errno = %d", errno);
+ nost++;
+ if (nost == num_osts)
+ nost = 0;
+ }
+
+ nost = 0;
+ for (i = 0; i < LOV_MAX_STRIPE_COUNT; i++) {
+ rc = llapi_layout_ost_index_get(layout, i, &ost0);
+ ASSERTF(rc == 0, "errno = %d", errno);
+ ASSERTF(ost0 == nost, "ost=%"PRIu64" nost=%"PRIu64"",
+ ost0, nost);
+ nost++;
+ if (nost == num_osts)
+ nost = 0;
+ }
+ llapi_layout_free(layout);
+
+ nost = 0;
+ layout = llapi_layout_alloc();
+ ASSERTF(layout != NULL, "errno %d", errno);
+ for (i = LOV_MAX_STRIPE_COUNT-1; i >= 0; i--) {
+ rc = llapi_layout_ost_index_set(layout, i, nost);
+ ASSERTF(rc == 0, "errno = %d", errno);
+ rc = llapi_layout_ost_index_get(layout, i, &ost0);
+ ASSERTF(rc == 0, "errno = %d", errno);
+ nost++;
+ if (nost == num_osts)
+ nost = 0;
+ }
+
+ nost = 0;
+ for (i = LOV_MAX_STRIPE_COUNT-1; i <= 0; i--) {
+ rc = llapi_layout_ost_index_get(layout, i, &ost0);
+ ASSERTF(rc == 0, "errno = %d", errno);
+ ASSERTF(ost0 == nost, "ost=%"PRIu64", nost=%"PRIu64"",
+ ost0, nost);
+ nost++;
+ if (nost == num_osts)
+ nost = 0;
+ }
+ llapi_layout_free(layout);
+}
+
+#define T30FILE "f30"
+#define T30_DESC "create composite file, traverse components"
+void test30(void)
+{
+ int rc, fd;
+ uint64_t start[3], end[3];
+ uint64_t s, e;
+ struct llapi_layout *layout;
+ char path[PATH_MAX];
+
+ start[0] = 0;
+ end[0] = 64 * 1024 * 1024; /* 64m */
+ start[1] = end[0];
+ end[1] = 1 * 1024 * 1024 * 1024; /* 1G */
+ start[2] = end[1];
+ end[2] = LUSTRE_EOF;
+
+ if (num_osts < 2)
+ return;
+
+ snprintf(path, sizeof(path), "%s/%s", lustre_dir, T30FILE);
+
+ rc = unlink(path);
+ ASSERTF(rc >= 0 || errno == ENOENT, "errno = %d", errno);
+
+ layout = llapi_layout_alloc();
+ ASSERTF(layout != NULL, "errno %d", errno);
+
+ rc = llapi_layout_stripe_count_set(layout, 1);
+ ASSERTF(rc == 0, "errno %d", errno);
+
+ /* add component without adjusting previous component's extent
+ * end will fail. */
+ rc = llapi_layout_comp_add(layout);
+ ASSERTF(rc == -1 && errno == EINVAL, "rc %d, errno %d", rc, errno);
+
+ rc = llapi_layout_comp_extent_set(layout, start[0], end[0]);
+ ASSERTF(rc == 0, "errno %d", errno);
+
+ rc = llapi_layout_comp_add(layout);
+ ASSERTF(rc == 0, "errno %d", errno);
+
+ /* set non-contiguous extent will fail */
+ rc = llapi_layout_comp_extent_set(layout, end[0] * 2, end[1]);
+ ASSERTF(rc == -1 && errno == EINVAL, "rc %d, errno %d", rc, errno);
+
+ rc = llapi_layout_comp_extent_set(layout, start[1], end[1]);
+ ASSERTF(rc == 0, "errno %d", errno);
+
+ rc = llapi_layout_comp_add(layout);
+ ASSERTF(rc == 0, "errno %d", errno);
+
+ rc = llapi_layout_comp_extent_set(layout, start[2], end[2]);
+ ASSERTF(rc == 0, "errno %d", errno);
+
+ /* create composite file */
+ fd = llapi_layout_file_create(path, 0, 0660, layout);
+ ASSERTF(fd >= 0, "path = %s, fd = %d, errno = %d", path, fd, errno);
+
+ llapi_layout_free(layout);
+
+ /* traverse & verify all components */
+ layout = llapi_layout_get_by_path(path, 0);
+ ASSERTF(layout != NULL, "errno = %d", errno);
+
+ /* current component should be the tail component */
+ rc = llapi_layout_comp_extent_get(layout, &s, &e);
+ ASSERTF(rc == 0, "errno %d", errno);
+ ASSERTF(s == start[2] && e == end[2],
+ "s: %"PRIu64", e: %"PRIu64"", s, e);
+
+ rc = llapi_layout_comp_use(layout, LLAPI_LAYOUT_COMP_USE_FIRST);
+ ASSERTF(rc == 0, "rc %d, errno %d", rc, errno);
+
+ /* delete non-tail component will fail */
+ rc = llapi_layout_comp_del(layout);
+ ASSERTF(rc == -1 && errno == EINVAL, "rc %d, errno %d", rc, errno);
+
+ rc = llapi_layout_comp_extent_get(layout, &s, &e);
+ ASSERTF(rc == 0, "errno %d", errno);
+ ASSERTF(s == start[0] && e == end[0],
+ "s: %"PRIu64", e: %"PRIu64"", s, e);
+
+ rc = llapi_layout_comp_use(layout, LLAPI_LAYOUT_COMP_USE_NEXT);
+ ASSERTF(rc == 0, "rc %d, errno %d", rc, errno);
+
+ rc = llapi_layout_comp_extent_get(layout, &s, &e);
+ ASSERTF(rc == 0, "errno %d", errno);
+ ASSERTF(s == start[1] && e == end[1],
+ "s: %"PRIu64", e: %"PRIu64"", s, e);
+
+ rc = llapi_layout_comp_use(layout, LLAPI_LAYOUT_COMP_USE_NEXT);
+ ASSERTF(rc == 0, "rc %d, errno %d", rc, errno);
+
+ rc = llapi_layout_comp_del(layout);
+ ASSERTF(rc == 0, "errno %d", errno);
+
+ llapi_layout_free(layout);
+}
+
+#define T31FILE "f31"
+#define T31_DESC "add/delete component to/from existing file"
+void test31(void)
+{
+ int rc, fd, i;
+ uint64_t start[2], end[2];
+ uint64_t s, e;
+ uint32_t id[2];
+ struct llapi_layout *layout;
+ char path[PATH_MAX];
+
+ start[0] = 0;
+ end[0] = 64 * 1024 * 1024; /* 64m */
+ start[1] = end[0];
+ end[1] = LUSTRE_EOF;
+
+ if (num_osts < 2)
+ return;
+
+ snprintf(path, sizeof(path), "%s/%s", lustre_dir, T31FILE);
+
+ rc = unlink(path);
+ ASSERTF(rc >= 0 || errno == ENOENT, "errno = %d", errno);
+
+ layout = llapi_layout_alloc();
+ ASSERTF(layout != NULL, "errno %d", errno);
+
+ rc = llapi_layout_stripe_count_set(layout, 1);
+ ASSERTF(rc == 0, "errno %d", errno);
+
+ rc = llapi_layout_comp_extent_set(layout, start[0], end[0]);
+ ASSERTF(rc == 0, "errno %d", errno);
+
+ /* create composite file */
+ fd = llapi_layout_file_create(path, 0, 0660, layout);
+ ASSERTF(fd >= 0, "path = %s, fd = %d, errno = %d", path, fd, errno);
+ llapi_layout_free(layout);
+
+ layout = llapi_layout_alloc();
+ ASSERTF(layout != NULL, "errno %d", errno);
+
+ rc = llapi_layout_stripe_count_set(layout, 2);
+ ASSERTF(rc == 0, "errno %d", errno);
+
+ rc = llapi_layout_comp_extent_set(layout, start[1], end[1]);
+ ASSERTF(rc == 0, "errno %d", errno);
+
+ /* add comopnent to existing file */
+ rc = llapi_layout_file_comp_add(path, layout);
+ ASSERTF(rc == 0, "errno %d", errno);
+ llapi_layout_free(layout);
+
+ /* verify the composite layout after adding */
+ layout = llapi_layout_get_by_path(path, 0);
+ ASSERTF(layout != NULL, "errno = %d", errno);
+
+ rc = llapi_layout_comp_use(layout, LLAPI_LAYOUT_COMP_USE_FIRST);
+ ASSERTF(rc == 0, "rc %d, errno %d", rc, errno);
+ i = 0;
+ do {
+ rc = llapi_layout_comp_extent_get(layout, &s, &e);
+ ASSERTF(rc == 0 && i < 2, "i %d, errno %d", i, errno);
+ ASSERTF(s == start[i] && e == end[i],
+ "i: %d s: %"PRIu64", e: %"PRIu64"", i, s, e);
+
+ rc = llapi_layout_comp_id_get(layout, &id[i]);
+ ASSERTF(rc == 0 && id[i] != 0, "i %d, errno %d, id %d",
+ i, errno, id[i]);
+
+ rc = llapi_layout_comp_use(layout, LLAPI_LAYOUT_COMP_USE_NEXT);
+ ASSERTF(rc == 0 || i == 1, "i=%d rc=%d errno=%d", i, rc, errno);
+ i++;
+ } while (rc == 0);
+
+ /* Verify reverse iteration gives the same IDs as forward iteration */
+ rc = llapi_layout_comp_use(layout, LLAPI_LAYOUT_COMP_USE_LAST);
+ ASSERTF(rc == 0, "rc %d, errno %d", rc, errno);
+ do {
+ __u32 comp_id;
+
+ --i;
+ rc = llapi_layout_comp_id_get(layout, &comp_id);
+ ASSERTF(rc == 0 && comp_id == id[i],
+ "i %d, errno %d, id[] %u/%u", i, errno, id[i], comp_id);
+
+ rc = llapi_layout_comp_use(layout, LLAPI_LAYOUT_COMP_USE_PREV);
+ ASSERTF(rc == 0 || i == 0, "i=%d rc=%d errno=%d", i, rc, errno);
+ } while (rc == 0);
+
+ llapi_layout_free(layout);
+
+ /* delete non-tail component will fail */
+ rc = llapi_layout_file_comp_del(path, id[0], 0);
+ ASSERTF(rc < 0 && errno == EINVAL, "rc %d, errno %d", rc, errno);
+
+ rc = llapi_layout_file_comp_del(path, id[1], 0);
+ ASSERTF(rc == 0, "rc %d, errno %d", rc, errno);
+
+ /* verify the composite layout after deleting */
+ layout = llapi_layout_get_by_path(path, 0);
+ ASSERTF(layout != NULL, "errno = %d", errno);
+
+ rc = llapi_layout_comp_use(layout, LLAPI_LAYOUT_COMP_USE_FIRST);
+ ASSERTF(rc == 0, "rc %d, errno %d", rc, errno);
+
+ rc = llapi_layout_comp_extent_get(layout, &s, &e);
+ ASSERTF(rc == 0, "errno %d", errno);
+ ASSERTF(s == start[0] && e == end[0],
+ "s: %"PRIu64", e: %"PRIu64"", s, e);
+}
+
#define TEST_DESC_LEN 50
struct test_tbl_entry {
void (*tte_fn)(void);
};
static struct test_tbl_entry test_tbl[] = {
- { &test0, T0_DESC, false },
- { &test1, T1_DESC, false },
- { &test2, T2_DESC, false },
- { &test3, T3_DESC, false },
- { &test4, T4_DESC, false },
- { &test5, T5_DESC, false },
- { &test6, T6_DESC, false },
- { &test7, T7_DESC, false },
- { &test8, T8_DESC, false },
- { &test9, T9_DESC, false },
- { &test10, T10_DESC, false },
- { &test11, T11_DESC, false },
- { &test12, T12_DESC, false },
- { &test13, T13_DESC, false },
- { &test14, T14_DESC, false },
- { &test15, T15_DESC, false },
- { &test16, T16_DESC, false },
- { &test17, T17_DESC, false },
- { &test18, T18_DESC, false },
- { &test19, T19_DESC, false },
- { &test20, T20_DESC, false },
- { &test21, T21_DESC, false },
- { &test22, T22_DESC, false },
- { &test23, T23_DESC, false },
- { &test24, T24_DESC, false },
- { &test25, T25_DESC, false },
- { &test26, T26_DESC, false },
- { &test27, T27_DESC, false },
- { &test28, T28_DESC, false },
+ { .tte_fn = &test0, .tte_desc = T0_DESC, .tte_skip = false },
+ { .tte_fn = &test1, .tte_desc = T1_DESC, .tte_skip = false },
+ { .tte_fn = &test2, .tte_desc = T2_DESC, .tte_skip = false },
+ { .tte_fn = &test3, .tte_desc = T3_DESC, .tte_skip = false },
+ { .tte_fn = &test4, .tte_desc = T4_DESC, .tte_skip = false },
+ { .tte_fn = &test5, .tte_desc = T5_DESC, .tte_skip = false },
+ { .tte_fn = &test6, .tte_desc = T6_DESC, .tte_skip = false },
+ { .tte_fn = &test7, .tte_desc = T7_DESC, .tte_skip = false },
+ { .tte_fn = &test8, .tte_desc = T8_DESC, .tte_skip = false },
+ { .tte_fn = &test9, .tte_desc = T9_DESC, .tte_skip = false },
+ { .tte_fn = &test10, .tte_desc = T10_DESC, .tte_skip = false },
+ { .tte_fn = &test11, .tte_desc = T11_DESC, .tte_skip = false },
+ { .tte_fn = &test12, .tte_desc = T12_DESC, .tte_skip = false },
+ { .tte_fn = &test13, .tte_desc = T13_DESC, .tte_skip = false },
+ { .tte_fn = &test14, .tte_desc = T14_DESC, .tte_skip = false },
+ { .tte_fn = &test15, .tte_desc = T15_DESC, .tte_skip = false },
+ { .tte_fn = &test16, .tte_desc = T16_DESC, .tte_skip = false },
+ { .tte_fn = &test17, .tte_desc = T17_DESC, .tte_skip = false },
+ { .tte_fn = &test18, .tte_desc = T18_DESC, .tte_skip = false },
+ { .tte_fn = &test19, .tte_desc = T19_DESC, .tte_skip = false },
+ { .tte_fn = &test20, .tte_desc = T20_DESC, .tte_skip = false },
+ { .tte_fn = &test21, .tte_desc = T21_DESC, .tte_skip = false },
+ { .tte_fn = &test22, .tte_desc = T22_DESC, .tte_skip = false },
+ { .tte_fn = &test23, .tte_desc = T23_DESC, .tte_skip = false },
+ { .tte_fn = &test24, .tte_desc = T24_DESC, .tte_skip = false },
+ { .tte_fn = &test25, .tte_desc = T25_DESC, .tte_skip = false },
+ { .tte_fn = &test26, .tte_desc = T26_DESC, .tte_skip = false },
+ { .tte_fn = &test27, .tte_desc = T27_DESC, .tte_skip = false },
+ { .tte_fn = &test28, .tte_desc = T28_DESC, .tte_skip = false },
+ { .tte_fn = &test29, .tte_desc = T29_DESC, .tte_skip = false },
+ { .tte_fn = &test30, .tte_desc = T30_DESC, .tte_skip = false },
+ { .tte_fn = &test31, .tte_desc = T31_DESC, .tte_skip = false },
};
+
#define NUM_TESTS (sizeof(test_tbl) / sizeof(struct test_tbl_entry))
void print_test_desc(int test_num, const char *test_desc, const char *status)
return rc;
}
+/* 'str_tests' are the tests to be skipped, such as "1,3,4,.." */
+static void set_tests_skipped(char *str_tests)
+{
+ char *ptr = str_tests;
+ int tstno;
+
+ if (ptr == NULL || strlen(ptr) == 0)
+ return;
+
+ while (*ptr != '\0') {
+ tstno = strtoul(ptr, &ptr, 0);
+ if (tstno >= 0 && tstno < NUM_TESTS)
+ test_tbl[tstno].tte_skip = true;
+ if (*ptr == ',')
+ ptr++;
+ else
+ break;
+ }
+}
+
static void process_args(int argc, char *argv[])
{
int c;
- while ((c = getopt(argc, argv, "d:p:o:")) != -1) {
+ while ((c = getopt(argc, argv, "d:p:o:s:")) != -1) {
switch (c) {
case 'd':
lustre_dir = optarg;
case 'o':
num_osts = atoi(optarg);
break;
+ case 's':
+ set_tests_skipped(optarg);
+ break;
case '?':
fprintf(stderr, "Unknown option '%c'\n", optopt);
usage(argv[0]);