* 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", \
static char *lustre_dir;
static char *poolname;
+static bool run_list_provided;
static int num_osts = -1;
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);
}
{
int rc;
struct llapi_layout *layout;
- lustre_fid fid;
+ struct lu_fid fid;
char fidstr[4096];
char path[PATH_MAX];
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);
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);
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);
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);
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);
"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"
+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"
+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"
+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 try to 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 zero-length so it 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))
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;
}
}
}
+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]);
if (test(tst->tte_fn, tst->tte_desc, tst->tte_skip, i) != 0)
rc++;
}
+
return rc;
}