* GPL HEADER END
*/
/*
+ * Copyright (c) 2016, 2017, Intel Corporation.
+ */
+/*
* These tests exercise the llapi_layout API which abstracts the layout
* of a Lustre file behind an opaque data type. They assume a Lustre
* file system with at least 2 OSTs and a pool containing at least the
#include <sys/stat.h>
#include <getopt.h>
#include <inttypes.h>
+#include <sys/ioctl.h>
#define ERROR(fmt, ...) \
fprintf(stderr, "%s: %s:%d: %s: " fmt "\n", \
DIE("assertion '%s' failed: "fmt, #cond, ## __VA_ARGS__);\
} while (0) \
+#define IN_RANGE(value, low, high) ((value >= low) && (value <= high))
+
static char *lustre_dir;
static char *poolname;
+static bool run_list_provided;
static int num_osts = -1;
-void usage(char *prog)
+static void usage(char *prog)
{
printf("Usage: %s [-d lustre_dir] [-p pool_name] [-o num_osts] "
- "[-s $n,$m,..]\n", prog);
+ "[-s $n,$m,... (skip tests)] [-t $n,$m,... (run tests)]\n",
+ prog);
exit(0);
}
#define T0_STRIPE_SIZE 1048576
#define T0_OST_OFFSET (num_osts - 1)
#define T0_DESC "Read/write layout attributes then create a file"
-void test0(void)
+static void test0(void)
{
int rc;
int fd;
llapi_layout_free(layout);
}
-void __test1_helper(struct llapi_layout *layout)
+static void __test1_helper(struct llapi_layout *layout)
{
uint64_t ost0;
uint64_t ost1;
}
#define T1_DESC "Read test0 file by path and verify attributes"
-void test1(void)
+static void test1(void)
{
char path[PATH_MAX];
snprintf(path, sizeof(path), "%s/%s", lustre_dir, T0FILE);
struct llapi_layout *layout = llapi_layout_get_by_path(path, 0);
+
ASSERTF(layout != NULL, "errno = %d", errno);
__test1_helper(layout);
llapi_layout_free(layout);
}
#define T2_DESC "Read test0 file by FD and verify attributes"
-void test2(void)
+static void test2(void)
{
int fd;
int rc;
ASSERTF(fd >= 0, "open(%s): errno = %d", path, errno);
struct llapi_layout *layout = llapi_layout_get_by_fd(fd, 0);
+
ASSERTF(layout != NULL, "errno = %d", errno);
rc = close(fd);
}
#define T3_DESC "Read test0 file by FID and verify attributes"
-void test3(void)
+static void test3(void)
{
int rc;
struct llapi_layout *layout;
- lustre_fid fid;
+ struct lu_fid fid;
char fidstr[4096];
char path[PATH_MAX];
#define T4_STRIPE_COUNT 2
#define T4_STRIPE_SIZE 2097152
#define T4_DESC "Verify compatibility with 'lfs setstripe'"
-void test4(void)
+static void test4(void)
{
int rc;
uint64_t ost0;
uint64_t size;
const char *lfs = getenv("LFS");
char mypool[LOV_MAXPOOLNAME + 1] = { '\0' };
- char cmd[4096];
+ char cmd[PATH_MAX + 128];
char path[PATH_MAX];
snprintf(path, sizeof(path), "%s/%s", lustre_dir, T4FILE);
errno = 0;
struct llapi_layout *layout = llapi_layout_get_by_path(path, 0);
+
ASSERTF(layout != NULL, "errno = %d", errno);
rc = llapi_layout_stripe_count_get(layout, &count);
#define T5FILE "t5"
#define T5_DESC "llapi_layout_get_by_path ENOENT handling"
-void test5(void)
+static void test5(void)
{
int rc;
char path[PATH_MAX];
}
#define T6_DESC "llapi_layout_get_by_fd EBADF handling"
-void test6(void)
+static void test6(void)
{
errno = 0;
struct llapi_layout *layout = llapi_layout_get_by_fd(9999, 0);
+
ASSERTF(layout == NULL && errno == EBADF, "errno = %d", errno);
}
#define T7FILE "t7"
#define T7_DESC "llapi_layout_get_by_path EACCES handling"
-void test7(void)
+static void test7(void)
{
int fd;
int rc;
ASSERTF(rc == 0, "errno = %d", errno);
errno = 0;
struct llapi_layout *layout = llapi_layout_get_by_path(path, 0);
+
ASSERTF(layout == NULL && errno == EACCES, "errno = %d", errno);
rc = seteuid(myuid);
ASSERTF(rc == 0, "errno = %d", errno);
}
/* llapi_layout_get_by_path() returns default layout for file with no
- * striping attributes. */
+ * striping attributes.
+ */
#define T8FILE "t8"
#define T8_DESC "llapi_layout_get_by_path ENODATA handling"
-void test8(void)
+static void test8(void)
{
int fd;
int rc;
/* Verify llapi_layout_patter_set() return values for various inputs. */
#define T9_DESC "verify llapi_layout_pattern_set() return values"
-void test9(void)
+static void test9(void)
{
struct llapi_layout *layout;
int rc;
/* Verify stripe_count interfaces return errors as expected */
#define T10_DESC "stripe_count error handling"
-void test10(void)
+static void test10(void)
{
int rc;
uint64_t count;
/* Verify stripe_size interfaces return errors as expected */
#define T11_DESC "stripe_size error handling"
-void test11(void)
+static void test11(void)
{
int rc;
uint64_t size;
/* Verify pool_name interfaces return errors as expected */
#define T12_DESC "pool_name error handling"
-void test12(void)
+static void test12(void)
{
int rc;
struct llapi_layout *layout;
#define T13FILE "t13"
#define T13_STRIPE_COUNT 2
#define T13_DESC "ost_index error handling"
-void test13(void)
+static void test13(void)
{
int rc;
int fd;
/* Verify llapi_layout_file_create() returns errors as expected */
#define T14_DESC "llapi_layout_file_create error handling"
-void test14(void)
+static void test14(void)
{
int rc;
struct llapi_layout *layout = llapi_layout_alloc();
#define T15FILE "t15"
#define T15_STRIPE_COUNT 2
#define T15_DESC "Can't change striping attributes of existing file"
-void test15(void)
+static void test15(void)
{
int rc;
int fd;
/* Default stripe attributes are applied as expected. */
#define T16FILE "t16"
#define T16_DESC "Default stripe attributes are applied as expected"
-void test16(void)
+static void test16(void)
{
int rc;
int fd;
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 ||
+ IN_RANGE(dcount, LLAPI_LAYOUT_WIDE_MIN, LLAPI_LAYOUT_WIDE_MAX),
+ "%"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 ||
+ IN_RANGE(dcount, LLAPI_LAYOUT_WIDE_MIN, LLAPI_LAYOUT_WIDE_MAX),
+ "%"PRIu64" != %"PRIu64, fcount, dcount);
ASSERTF(fsize == dsize, "%"PRIu64" != %"PRIu64, fsize, dsize);
llapi_layout_free(filelayout);
/* Setting stripe count to LLAPI_LAYOUT_WIDE uses all available OSTs. */
#define T17FILE "t17"
#define T17_DESC "LLAPI_LAYOUT_WIDE is honored"
-void test17(void)
+static void test17(void)
{
int rc;
int fd;
/* Setting pool with "fsname.pool" notation. */
#define T18FILE "t18"
#define T18_DESC "Setting pool with fsname.pool notation"
-void test18(void)
+static void test18(void)
{
int rc;
int fd;
}
#define T19_DESC "Maximum length pool name is NULL-terminated"
-void test19(void)
+static void test19(void)
{
struct llapi_layout *layout;
char *name = "0123456789abcde";
#define T20FILE "t20"
#define T20_DESC "LLAPI_LAYOUT_DEFAULT is honored"
-void test20(void)
+static void test20(void)
{
int rc;
int fd;
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);
}
#define T21_DESC "llapi_layout_file_create fails for non-Lustre file"
-void test21(void)
+static void test21(void)
{
struct llapi_layout *layout;
char template[PATH_MAX];
#define T22FILE "t22"
#define T22_DESC "llapi_layout_file_create applied mode correctly"
-void test22(void)
+static void test22(void)
{
int rc;
int fd;
rc = unlink(path);
ASSERTF(rc == 0 || errno == ENOENT, "errno = %d", errno);
- umask_orig = umask(S_IWGRP | S_IWOTH);
+ umask_orig = umask(0022);
fd = llapi_layout_file_create(path, 0, mode_in, NULL);
ASSERTF(fd >= 0, "errno = %d", errno);
}
#define T23_DESC "llapi_layout_get_by_path fails for non-Lustre file"
-void test23(void)
+static void test23(void)
{
struct llapi_layout *layout;
char template[PATH_MAX];
}
/* llapi_layout_get_by_path(path, LAYOUT_GET_EXPECTED) returns expected layout
- * for file with unspecified layout. */
+ * for file with unspecified layout.
+ */
#define T24FILE "t24"
#define T24_DESC "LAYOUT_GET_EXPECTED works with existing file"
-void test24(void)
+static void test24(void)
{
int fd;
int rc;
}
/* llapi_layout_get_by_path(path, LAYOUT_GET_EXPECTED) returns expected layout
- * for directory with unspecified layout. */
+ * for directory with unspecified layout.
+ */
#define T25DIR "d25"
#define T25_DESC "LAYOUT_GET_EXPECTED works with directory"
-void test25(void)
+static void test25(void)
{
int rc;
struct llapi_layout *layout;
}
/* llapi_layout_get_by_path(path, LAYOUT_GET_EXPECTED) correctly combines
- * specified attributes of parent directory with attributes filesystem root. */
+ * specified attributes of parent directory with attributes filesystem root.
+ */
#define T26DIR "d26"
#define T26_DESC "LAYOUT_GET_EXPECTED partially specified parent"
#define T26_STRIPE_SIZE (1048576 * 4)
-void test26(void)
+static void test26(void)
{
int rc;
struct llapi_layout *layout;
uint64_t size;
uint64_t pattern;
char dir[PATH_MAX];
- char cmd[4096];
+ char cmd[PATH_MAX + 64];
snprintf(dir, sizeof(dir), "%s/%s", lustre_dir, T26DIR);
rc = rmdir(dir);
}
/* llapi_layout_get_by_path(path, LAYOUT_GET_EXPECTED) work with
- * non existing file. */
+ * non existing file.
+ */
#define T27DIR "d27"
#define T27_DESC "LAYOUT_GET_EXPECTED with non existing file"
#define T27_STRIPE_SIZE (1048576 * 3)
-void test27(void)
+static void test27(void)
{
int rc;
struct llapi_layout *layout;
uint64_t count;
uint64_t size;
uint64_t pattern;
- char dirpath[PATH_MAX];
- char filepath[PATH_MAX];
- char cmd[4096];
+ char dirpath[PATH_MAX + 128];
+ char filepath[PATH_MAX * 2];
+ char cmd[PATH_MAX * 2];
- snprintf(dirpath, sizeof(dirpath), "%s/%s", lustre_dir, T27DIR);
+ snprintf(dirpath, sizeof(dirpath) - 1, "%s/%s", lustre_dir, T27DIR);
snprintf(filepath, sizeof(filepath), "%s/nonesuch", dirpath);
rc = rmdir(dirpath);
}
/* llapi_layout_stripe_count_get returns LLAPI_LAYOUT_WIDE for a directory
- * with a stripe_count of -1. */
+ * with a stripe_count of -1.
+ */
#define T28DIR "d28"
#define T28_DESC "LLAPI_LAYOUT_WIDE returned as expected"
-void test28(void)
+static void test28(void)
{
int rc;
struct llapi_layout *layout;
const char *lfs = getenv("LFS");
uint64_t count;
char dirpath[PATH_MAX];
- char cmd[4096];
+ char cmd[PATH_MAX + 64];
snprintf(dirpath, sizeof(dirpath), "%s/%s", lustre_dir, T28DIR);
#define T29FILE "f29"
#define T29_DESC "set ost index to non-zero stripe number"
-void test29(void)
+static void test29(void)
{
int rc, fd, i;
uint64_t ost0, ost1, nost;
#define T30FILE "f30"
#define T30_DESC "create composite file, traverse components"
-void test30(void)
+static void test30(void)
{
int rc, fd;
uint64_t start[3], end[3];
ASSERTF(rc == 0, "errno %d", errno);
/* add component without adjusting previous component's extent
- * end will fail. */
+ * end will fail.
+ */
rc = llapi_layout_comp_add(layout);
ASSERTF(rc == -1 && errno == EINVAL, "rc %d, errno %d", rc, errno);
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] * 2, end[1]);
+ ASSERTF(rc == 0, "errno %d", errno);
+ rc = llapi_layout_sanity(layout, false, false);
+ ASSERTF(rc == 12 /*LSE_NOT_ADJACENT_PREV*/, "rc %d", rc);
rc = llapi_layout_comp_extent_set(layout, start[1], end[1]);
ASSERTF(rc == 0, "errno %d", errno);
ASSERTF(s == start[2] && e == end[2],
"s: %"PRIu64", e: %"PRIu64"", s, e);
- rc = llapi_layout_comp_move(layout, LLAPI_LAYOUT_COMP_POS_FIRST);
+ 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 */
ASSERTF(s == start[0] && e == end[0],
"s: %"PRIu64", e: %"PRIu64"", s, e);
- rc = llapi_layout_comp_move(layout, LLAPI_LAYOUT_COMP_POS_NEXT);
+ 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(s == start[1] && e == end[1],
"s: %"PRIu64", e: %"PRIu64"", s, e);
- rc = llapi_layout_comp_move(layout, LLAPI_LAYOUT_COMP_POS_NEXT);
+ 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);
#define T31FILE "f31"
#define T31_DESC "add/delete component to/from existing file"
-void test31(void)
+static void test31(void)
{
int rc, fd, i;
uint64_t start[2], end[2];
layout = llapi_layout_get_by_path(path, 0);
ASSERTF(layout != NULL, "errno = %d", errno);
- rc = llapi_layout_comp_move(layout, LLAPI_LAYOUT_COMP_POS_FIRST);
+ rc = llapi_layout_comp_use(layout, LLAPI_LAYOUT_COMP_USE_FIRST);
ASSERTF(rc == 0, "rc %d, errno %d", rc, errno);
i = 0;
do {
ASSERTF(rc == 0 && id[i] != 0, "i %d, errno %d, id %d",
i, errno, id[i]);
- rc = llapi_layout_comp_move(layout, LLAPI_LAYOUT_COMP_POS_NEXT);
- ASSERTF(rc >= 0, "i %d, rc %d, errno %d", i, rc, errno);
-
+ 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]);
+ 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]);
+ 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_move(layout, LLAPI_LAYOUT_COMP_POS_FIRST);
+ 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);
"s: %"PRIu64", e: %"PRIu64"", s, e);
}
-#define TEST_DESC_LEN 50
+#define T32FILE "t32"
+#define T32_STRIPE_COUNT (num_osts*2)
+#define T32_DESC "Test overstriping with layout_file_create"
+static void test32(void)
+{
+ int rc;
+ int fd;
+ uint64_t count;
+ struct llapi_layout *layout = llapi_layout_alloc();
+ void *lmdbuf = NULL;
+ struct lov_user_md *lmd;
+ char path[PATH_MAX];
+
+ ASSERTF(layout != NULL, "errno %d", errno);
+
+ /* Maximum possible, to be on the safe side - num_osts could be large */
+ lmdbuf = malloc(XATTR_SIZE_MAX);
+ ASSERTF(lmdbuf != NULL, "errno %d", errno);
+ lmd = lmdbuf;
+
+ snprintf(path, sizeof(path), "%s/%s", lustre_dir, T32FILE);
+
+ rc = unlink(path);
+ ASSERTF(rc >= 0 || errno == ENOENT, "errno = %d", errno);
+
+ /* stripe count */
+ rc = llapi_layout_stripe_count_set(layout, T32_STRIPE_COUNT);
+ ASSERTF(rc == 0, "errno = %d", errno);
+ rc = llapi_layout_stripe_count_get(layout, &count);
+ ASSERTF(rc == 0 && count == T32_STRIPE_COUNT, "%"PRIu64" != %d", count,
+ T32_STRIPE_COUNT);
+
+ rc = llapi_layout_pattern_set(layout, LLAPI_LAYOUT_OVERSTRIPING);
+ ASSERTF(rc == 0, "errno = %d", errno);
+
+ /* create */
+ fd = llapi_layout_file_create(path, 0, 0660, layout);
+ ASSERTF(fd >= 0, "path = %s, errno = %d", path, errno);
+
+ rc = ioctl(fd, LL_IOC_LOV_GETSTRIPE_NEW, lmdbuf);
+ ASSERTF(rc == 0, "errno = %d", errno);
+
+ count = lmd->lmm_stripe_count;
+ ASSERTF(count == T32_STRIPE_COUNT,
+ "stripe count (%"PRIu64") not equal to expected (%d)",
+ count, T32_STRIPE_COUNT);
+
+ rc = close(fd);
+ ASSERTF(rc == 0, "errno = %d", errno);
+ llapi_layout_free(layout);
+ free(lmdbuf);
+}
+
+#define T33FILE "t33"
+#define T33_STRIPE_COUNT (num_osts*2)
+#define T33_DESC "Test overstriping with llapi_file_open"
+static void test33(void)
+{
+ int rc;
+ int fd;
+ uint64_t count;
+ void *lmdbuf = NULL;
+ struct lov_user_md *lmd;
+ char path[PATH_MAX];
+
+ /* Maximum possible, to be on the safe side - num_osts could be large */
+ lmdbuf = malloc(XATTR_SIZE_MAX);
+ ASSERTF(lmdbuf != NULL, "errno %d", errno);
+ lmd = lmdbuf;
+
+ snprintf(path, sizeof(path), "%s/%s", lustre_dir, T33FILE);
+
+ rc = unlink(path);
+ ASSERTF(rc >= 0 || errno == ENOENT, "errno = %d", errno);
+
+ fd = llapi_file_open(path, O_CREAT | O_RDWR, 0660, 0, -1, num_osts*2,
+ LOV_PATTERN_RAID0 | LOV_PATTERN_OVERSTRIPING);
+ ASSERTF(fd >= 0, "path = %s, errno = %d", path, errno);
+
+ rc = ioctl(fd, LL_IOC_LOV_GETSTRIPE_NEW, lmdbuf);
+ ASSERTF(rc == 0, "errno = %d", errno);
+
+ count = lmd->lmm_stripe_count;
+ ASSERTF(count == T33_STRIPE_COUNT,
+ "stripe count (%"PRIu64") not equal to expected (%d)",
+ count, T33_STRIPE_COUNT);
+
+ rc = close(fd);
+ ASSERTF(rc == 0, "errno = %d", errno);
+ free(lmdbuf);
+}
+
+#define T34FILE "f34"
+#define T34_DESC "create simple valid & invalid self extending layouts"
+static void test34(void)
+{
+ int rc, fd;
+ uint64_t start[4], end[4];
+ struct llapi_layout *layout;
+ char path[PATH_MAX];
+
+ start[0] = 0;
+ end[0] = 10 * 1024 * 1024; /* 10m */
+ start[1] = end[0];
+ end[1] = 1024 * 1024 * 1024; /* 1G */
+ start[2] = end[1];
+ end[2] = 10ull * 1024 * 1024 * 1024; /* 10G */
+ start[3] = end[2];
+ end[3] = LUSTRE_EOF;
+
+ if (num_osts < 2)
+ return;
+
+ snprintf(path, sizeof(path), "%s/%s", lustre_dir, T34FILE);
+
+ 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);
+
+ rc = llapi_layout_comp_extent_set(layout, start[1], end[1]);
+ ASSERTF(rc == 0, "errno %d", errno);
+
+ rc = llapi_layout_comp_flags_set(layout, LCME_FL_EXTENSION);
+ ASSERTF(rc == 0, "errno %d", errno);
+
+ /* Invalid size, too small - < 64 MiB */
+ rc = llapi_layout_extension_size_set(layout, 32 << 20);
+ ASSERTF(rc == -1, "errno %d", errno);
+
+ /* too large - > 4 TiB */
+ rc = llapi_layout_extension_size_set(layout, 5ull << 40);
+ ASSERTF(rc == -1, "errno %d", errno);
+
+ /* Valid size, 64 MiB */
+ rc = llapi_layout_extension_size_set(layout, 64 << 20);
+ 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);
+
+ /* Set extension space flag on adjacent components:
+ * This is invalid, but can't be checked until we create the file.
+ */
+ rc = llapi_layout_comp_flags_set(layout, LCME_FL_EXTENSION);
+ ASSERTF(rc == 0, "errno %d", errno);
+
+ fd = llapi_layout_file_create(path, 0, 0660, layout);
+ ASSERTF(fd = -1, "path = %s, fd = %d, errno = %d", path, fd, errno);
+
+ /* Delete incorrect component */
+ rc = llapi_layout_comp_del(layout);
+ ASSERTF(rc == 0, "errno %d", errno);
+
+ rc = llapi_layout_comp_add(layout);
+ ASSERTF(rc == 0, "errno %d", errno);
+
+ /* Convert this comp to 0-len that can be followed by extension space */
+ rc = llapi_layout_comp_extent_set(layout, start[2], start[2]);
+ 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[3]);
+ ASSERTF(rc == 0, "errno %d", errno);
+
+ rc = llapi_layout_comp_flags_set(layout, LCME_FL_EXTENSION);
+ 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);
+
+ rc = llapi_layout_sanity(layout, false, false);
+ ASSERTF(rc == 0, "errno %d", errno);
+}
+
+#define TEST_DESC_LEN 80
struct test_tbl_entry {
void (*tte_fn)(void);
char tte_desc[TEST_DESC_LEN];
{ .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 },
+ { .tte_fn = &test32, .tte_desc = T32_DESC, .tte_skip = false },
+ { .tte_fn = &test33, .tte_desc = T33_DESC, .tte_skip = false },
+ { .tte_fn = &test34, .tte_desc = T34_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)
+static void print_test_desc(int test_num, const char *test_desc,
+ const char *status)
{
int i;
}
/* This function runs a single test by forking the process. This way,
- * if there is a segfault during a test, the test program won't crash. */
-int test(void (*test_fn)(), const char *test_desc, bool test_skip, int test_num)
+ * if there is a segfault during a test, the test program won't crash.
+ */
+static int test(void (*test_fn)(), const char *test_desc, bool test_skip,
+ int test_num)
{
int rc = 0;
pid_t pid;
char status_buf[128];
if (test_skip) {
- print_test_desc(test_num, test_desc, "skip");
+ if (!run_list_provided)
+ print_test_desc(test_num, test_desc, "skip");
return 0;
}
print_test_desc(test_num, test_desc, status_buf);
} else if (pid == 0) {
/* Run the test in the child process. Exit with 0 for success,
- * non-zero for failure */
+ * non-zero for failure
+ */
test_fn();
exit(0);
}
}
}
+static void set_tests_to_run(char *str_tests)
+{
+ char *ptr = str_tests;
+ int tstno;
+ int i = 0;
+
+ if (ptr == NULL || strlen(ptr) == 0)
+ return;
+
+ for (i = 0; i < NUM_TESTS ; i++)
+ test_tbl[i].tte_skip = true;
+
+ while (*ptr != '\0') {
+ tstno = strtoul(ptr, &ptr, 0);
+ if (tstno >= 0 && tstno < NUM_TESTS)
+ test_tbl[tstno].tte_skip = false;
+ if (*ptr == ',')
+ ptr++;
+ else
+ break;
+ }
+}
+
static void process_args(int argc, char *argv[])
{
int c;
- while ((c = getopt(argc, argv, "d:p:o:s:")) != -1) {
+ while ((c = getopt(argc, argv, "d:p:o:s:t:")) != -1) {
switch (c) {
case 'd':
lustre_dir = optarg;
case 's':
set_tests_skipped(optarg);
break;
+ case 't':
+ run_list_provided = true;
+ set_tests_to_run(optarg);
+ break;
case '?':
fprintf(stderr, "Unknown option '%c'\n", optopt);
usage(argv[0]);
}
/* Play nice with Lustre test scripts. Non-line buffered output
- * stream under I/O redirection may appear incorrectly. */
+ * stream under I/O redirection may appear incorrectly.
+ */
setvbuf(stdout, NULL, _IOLBF, 0);
for (i = 0; i < NUM_TESTS; i++) {
struct test_tbl_entry *tst = &test_tbl[i];
+
if (test(tst->tte_fn, tst->tte_desc, tst->tte_skip, i) != 0)
rc++;
}
+
return rc;
}