/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
* vim:expandtab:shiftwidth=8:tabstop=8:
*
- * Lustre Light user test program
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
- * Copyright (c) 2002, 2003 Cluster File Systems, Inc.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
*
- * This file is part of Lustre, http://www.lustre.org.
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
*
- * Lustre is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
*
- * Lustre is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
*
- * You should have received a copy of the GNU General Public License
- * along with Lustre; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lustre/liblustre/tests/sanity.c
+ *
+ * Lustre Light user test program
*/
#define _BSD_SOURCE
+#define _FILE_OFFSET_BITS 64
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
-#include <sys/queue.h>
#include <signal.h>
#include <errno.h>
#include <dirent.h>
+#include <sys/uio.h>
+#include <sys/time.h>
+#include <time.h>
+#include <liblustre.h>
#include "test_common.h"
+#include <lustre/liblustreapi.h>
+
+#define _npages (2048)
+
+void *buf_alloc;
+int buf_size;
+int opt_verbose;
+struct timeval start;
+
+extern char *lustre_path;
-#define ENTRY(str) \
+#define ENTER(str) \
do { \
char buf[100]; \
int len; \
- sprintf(buf, "===== START: %s ", (str)); \
+ gettimeofday(&start, NULL); \
+ sprintf(buf, "===== START %s: %s %ld", __FUNCTION__, \
+ (str), (long)start.tv_sec); \
len = strlen(buf); \
if (len < 79) { \
memset(buf+len, '=', 100-len); \
#define LEAVE() \
do { \
- printf("----- END TEST successfully ---"); \
- printf("-----------------------------"); \
- printf("-------------------\n"); \
+ struct timeval stop; \
+ char buf[100] = { '\0' }; \
+ int len = sizeof(buf) - 1; \
+ long usec; \
+ gettimeofday(&stop, NULL); \
+ usec = (stop.tv_sec - start.tv_sec) * 1000000 + \
+ (stop.tv_usec - start.tv_usec); \
+ len = snprintf(buf, len, \
+ "===== END TEST %s: successfully (%gs)", \
+ __FUNCTION__, (double)usec / 1000000); \
+ if (len < 79) { \
+ memset(buf+len, '=', sizeof(buf) - len); \
+ buf[79] = '\n'; \
+ buf[80] = 0; \
+ } \
+ printf("%s", buf); \
+ return 0; \
} while (0)
#define MAX_PATH_LENGTH 4096
-void t1()
+int t1(char *name)
{
- char *path="/mnt/lustre/test_t1";
- ENTRY("create/delete");
+ char path[MAX_PATH_LENGTH] = "";
+
+ ENTER("touch+unlink");
+ snprintf(path, MAX_PATH_LENGTH, "%s/test_t1", lustre_path);
+
+ if (opt_verbose)
+ printf("touch+unlink %s\n", path);
t_touch(path);
t_unlink(path);
LEAVE();
}
-void t2()
+int t2(char *name)
{
- char *path="/mnt/lustre/test_t2";
- ENTRY("mkdir/rmdir");
+ char path[MAX_PATH_LENGTH] = "";
+
+ ENTER("mkdir/rmdir");
+ snprintf(path, MAX_PATH_LENGTH, "%s/test_t2", lustre_path);
t_mkdir(path);
t_rmdir(path);
LEAVE();
}
-void t3()
+int t3(char *name)
{
- char *path="/mnt/lustre/test_t3";
- ENTRY("regular stat");
+ char path[MAX_PATH_LENGTH] = "";
+
+ ENTER("regular stat");
+ snprintf(path, MAX_PATH_LENGTH, "%s/test_t3", lustre_path);
t_touch(path);
t_check_stat(path, NULL);
LEAVE();
}
-void t4()
+int t4(char *name)
{
- char *path="/mnt/lustre/test_t4";
- ENTRY("dir stat");
+ char path[MAX_PATH_LENGTH] = "";
+
+ ENTER("dir stat");
+ snprintf(path, MAX_PATH_LENGTH, "%s/test_t4", lustre_path);
t_mkdir(path);
t_check_stat(path, NULL);
LEAVE();
}
-void t6()
+int t6(char *name)
{
- char *path="/mnt/lustre/test_t6";
- char *path2="/mnt/lustre/test_t6_link";
- ENTRY("symlink");
+ char path[MAX_PATH_LENGTH] = "";
+ char path2[MAX_PATH_LENGTH] = "";
+
+ ENTER("symlink");
+ snprintf(path, MAX_PATH_LENGTH, "%s/test_t6", lustre_path);
+ snprintf(path2, MAX_PATH_LENGTH, "%s/test_t6_link", lustre_path);
t_touch(path);
t_symlink(path, path2);
LEAVE();
}
-void t7()
+int t6b(char *name)
{
- char *path="/mnt/lustre/test_t7";
+ char path[MAX_PATH_LENGTH] = "";
+ char path2[MAX_PATH_LENGTH] = "";
+ char cwd[MAX_PATH_LENGTH] = "";
+ char *tmp;
+ int fd;
+
+ ENTER("symlink + chdir and open");
+ snprintf(path, MAX_PATH_LENGTH, "%s/test_t6b", lustre_path);
+ snprintf(path2, MAX_PATH_LENGTH, "%s/test_t6b_link", lustre_path);
+
+ t_mkdir(path);
+ t_symlink(path, path2);
+ t_check_stat(path2, NULL);
+
+ tmp = getcwd(cwd, MAX_PATH_LENGTH);
+ if (tmp == NULL) {
+ fprintf(stderr, "current path too long to fit in "
+ "MAX_PATH_LENGTH?\n");
+ LEAVE();
+ }
+ t_chdir(path2);
+ t_chdir(cwd);
+ t_rmdir(path);
+ t_touch(path);
+
+ fd = t_open(path2);
+ t_close(fd);
+
+ t_unlink(path2);
+ t_unlink(path);
+ LEAVE();
+}
+
+int t7(char *name)
+{
+ char path[MAX_PATH_LENGTH] = "";
int rc;
- ENTRY("mknod");
+
+ ENTER("mknod");
+ snprintf(path, MAX_PATH_LENGTH, "%s/test_t7", lustre_path);
if (geteuid() != 0) {
rc = mknod(path, S_IFCHR | 0644, (5<<8 | 4));
LEAVE();
}
-void t8()
+int t8(char *name)
{
- char *path="/mnt/lustre/test_t8";
- ENTRY("chmod");
+ char path[MAX_PATH_LENGTH] = "";
+ ENTER("chmod");
+ snprintf(path, MAX_PATH_LENGTH, "%s/test_t8", lustre_path);
+
+ /* Check file. */
t_touch(path);
t_chmod_raw(path, 0700);
t_check_stat(path, NULL);
t_unlink(path);
+
+ /* Check dir. */
+ t_mkdir(path);
+ t_chmod_raw(path, 0700);
+ t_check_stat(path, NULL);
+ t_rmdir(path);
+
LEAVE();
}
-void t9()
+int t9(char *name)
{
- char *path="/mnt/lustre/test_t9";
- char *path2="/mnt/lustre/test_t9_link";
- ENTRY("hard link");
+ char path[MAX_PATH_LENGTH] = "";
+ char path2[MAX_PATH_LENGTH] = "";
+
+ ENTER("hard link");
+ snprintf(path, MAX_PATH_LENGTH, "%s/test_t9", lustre_path);
+ snprintf(path2, MAX_PATH_LENGTH, "%s/test_t9_link", lustre_path);
t_touch(path);
t_link(path, path2);
LEAVE();
}
-void t10()
+int t10(char *name)
{
- char *dir1="/mnt/lustre/test_t10_dir1";
- char *dir2="/mnt/lustre/test_t10_dir2";
- char *path1="/mnt/lustre/test_t10_reg1";
- char *path2="/mnt/lustre/test_t10_reg2";
- char *rename1="/mnt/lustre/test_t10_dir1/rename1";
- char *rename2="/mnt/lustre/test_t10_dir2/rename2";
- char *rename3="/mnt/lustre/test_t10_dir2/rename3";
- ENTRY("rename");
+ char dir1[MAX_PATH_LENGTH] = "";
+ char dir2[MAX_PATH_LENGTH] = "";
+ char path1[MAX_PATH_LENGTH] = "";
+ char path2[MAX_PATH_LENGTH] = "";
+ char rename1[MAX_PATH_LENGTH] = "";
+ char rename2[MAX_PATH_LENGTH] = "";
+ char rename3[MAX_PATH_LENGTH] = "";
+
+ ENTER("rename");
+ snprintf(dir1, MAX_PATH_LENGTH, "%s/test_t10_dir1", lustre_path);
+ snprintf(dir2, MAX_PATH_LENGTH, "%s/test_t10_dir2", lustre_path);
+ snprintf(path1, MAX_PATH_LENGTH, "%s/test_t10_reg1", lustre_path);
+ snprintf(path2, MAX_PATH_LENGTH, "%s/test_t10_reg2", lustre_path);
+ snprintf(rename1, MAX_PATH_LENGTH, "%s/test_t10_dir1/rename1", lustre_path);
+ snprintf(rename2, MAX_PATH_LENGTH, "%s/test_t10_dir2/rename2", lustre_path);
+ snprintf(rename3, MAX_PATH_LENGTH, "%s/test_t10_dir2/rename3", lustre_path);
t_mkdir(dir1);
t_mkdir(dir2);
LEAVE();
}
-void t11()
+int t11(char *name)
{
- char *base="/mnt/lustre";
+ char *base=lustre_path;
char path[MAX_PATH_LENGTH], path2[MAX_PATH_LENGTH];
int i, j, level = 5, nreg = 5;
- ENTRY("deep tree");
+ ENTER("deep tree");
safe_strncpy(path, base, MAX_PATH_LENGTH);
safe_strncpy(path, base, MAX_PATH_LENGTH);
for (j = 1; j < i; j++)
strcat(path, "/dir");
-
+
for (j = 0; j < nreg; j++) {
sprintf(path2, "%s/file%d", path, j);
t_unlink(path2);
LEAVE();
}
-void t12()
+int t12(char *name)
{
- char *dir="/mnt/lustre/test_t12_dir";
+ char dir[MAX_PATH_LENGTH] = "";
char buf[1024*128];
int fd;
- ENTRY("empty directory readdir");
+ ENTER("empty directory readdir");
+ snprintf(dir, MAX_PATH_LENGTH, "%s/test_t12_dir", lustre_path);
t_mkdir(dir);
fd = t_opendir(dir);
LEAVE();
}
-void t13()
+int t13(char *name)
{
- char *dir="/mnt/lustre/test_t13_dir/";
- char name[1024];
+ char dir[MAX_PATH_LENGTH] = "";
+ char path[1024];
char buf[1024];
const int nfiles = 20;
char *prefix = "test13_filename_prefix_";
int fd, i;
- ENTRY("multiple entries directory readdir");
+ ENTER("multiple entries directory readdir");
+ snprintf(dir, MAX_PATH_LENGTH, "%s/test_t13_dir/", lustre_path);
t_mkdir(dir);
printf("Creating %d files...\n", nfiles);
for (i = 0; i < nfiles; i++) {
- sprintf(name, "%s%s%05d", dir, prefix, i);
- t_touch(name);
+ sprintf(path, "%s%s%05d", dir, prefix, i);
+ t_touch(path);
}
fd = t_opendir(dir);
t_ls(fd, buf, sizeof(buf));
t_close(fd);
printf("Cleanup...\n");
for (i = 0; i < nfiles; i++) {
- sprintf(name, "%s%s%05d", dir, prefix, i);
- t_unlink(name);
+ sprintf(path, "%s%s%05d", dir, prefix, i);
+ t_unlink(path);
}
t_rmdir(dir);
LEAVE();
}
-void t14()
+int t14(char *name)
{
- char *dir="/mnt/lustre/test_t14_dir/";
- char name[1024];
+ char dir[MAX_PATH_LENGTH] = "";
+ char path[1024];
char buf[1024];
const int nfiles = 256;
char *prefix = "test14_filename_long_prefix_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA___";
- struct dirent64 *ent;
+ cfs_dirent_t *ent;
int fd, i, rc, pos, index;
- loff_t base = 0;
- ENTRY(">1 block(4k) directory readdir");
-
- t_mkdir(dir);
+ loff_t base = 0;
+ ENTER(">1 block(4k) directory readdir");
+ snprintf(dir, MAX_PATH_LENGTH, "%s/test_t14_dir/", lustre_path);
+
+ rc = mkdir(dir, 0755);
+ if (rc < 0 && errno != EEXIST) {
+ printf("mkdir(%s) error: %s\n", dir, strerror(errno));
+ exit(1);
+ }
printf("Creating %d files...\n", nfiles);
for (i = 0; i < nfiles; i++) {
- sprintf(name, "%s%s%05d", dir, prefix, i);
- t_touch(name);
+ sprintf(path, "%s%s%05d", dir, prefix, i);
+ t_touch(path);
}
fd = t_opendir(dir);
printf("Listing...\n");
index = 0;
- while ((rc = getdirentries64(fd, buf, 1024, &base)) > 0) {
- pos = 0;
- while (pos < rc) {
+ while ((rc = getdirentries64(fd, buf, 1024, &base)) > 0) {
+ pos = 0;
+ while (pos < rc) {
char *item;
- ent = (struct dirent64 *) ((char*) buf + pos);
+ ent = (void *) buf + pos;
item = (char *) ent->d_name;
if (!strcmp(item, ".") || !strcmp(item, ".."))
goto iter;
if (strstr(item, prefix) != item) {
printf("found bad name %s\n", item);
- exit(-1);
+ return(-1);
}
- printf("[%03d]: %s\n",
+ printf("[%03d]: %s\t",
index++, item + strlen(prefix));
iter:
- pos += ent->d_reclen;
- }
- }
- if (rc < 0) {
- printf("getdents error %d\n", rc);
- exit(-1);
- }
+ pos += ent->d_reclen;
+ }
+ }
+ printf("\n");
+ if (rc < 0) {
+ printf("getdents error %d\n", rc);
+ return(-1);
+ }
if (index != nfiles) {
printf("get %d files != %d\n", index, nfiles);
- exit(-1);
+ return(-1);
}
t_close(fd);
printf("Cleanup...\n");
for (i = 0; i < nfiles; i++) {
- sprintf(name, "%s%s%05d", dir, prefix, i);
- t_unlink(name);
+ sprintf(path, "%s%s%05d", dir, prefix, i);
+ t_unlink(path);
}
t_rmdir(dir);
LEAVE();
}
-void t15()
+int t15(char *name)
{
- char *file = "/mnt/lustre/test_t15_file";
+ char file[MAX_PATH_LENGTH] = "";
int fd;
- ENTRY("open-stat-close");
+ ENTER("open-stat-close");
+ snprintf(file, MAX_PATH_LENGTH, "%s/test_t15_file", lustre_path);
t_touch(file);
fd = t_open(file);
LEAVE();
}
-void t16()
+int t16(char *name)
{
- char *file = "/mnt/lustre/test_t16_file";
- int fd;
- ENTRY("small-write-read");
+ char file[MAX_PATH_LENGTH] = "";
+ ENTER("small-write-read");
+ snprintf(file, MAX_PATH_LENGTH, "%s/test_t16_file", lustre_path);
t_echo_create(file, "aaaaaaaaaaaaaaaaaaaaaa");
t_grep(file, "aaaaaaaaaaaaaaaaaaaaaa");
LEAVE();
}
-void t17()
+int t17(char *name)
{
- char *file = "/mnt/lustre/test_t17_file";
+ char file[MAX_PATH_LENGTH] = "";
int fd;
- ENTRY("open-unlink without close");
+ ENTER("open-unlink without close");
+ snprintf(file, MAX_PATH_LENGTH, "%s/test_t17_file", lustre_path);
fd = open(file, O_WRONLY | O_CREAT, 0666);
if (fd < 0) {
printf("failed to create file: %s\n", strerror(errno));
- exit(-1);
+ return(-1);
}
t_unlink(file);
LEAVE();
}
-void t18()
+int t18(char *name)
{
- char *file = "/mnt/lustre/test_t18_file";
+ char file[MAX_PATH_LENGTH] = "";
char buf[128];
int fd, i;
struct stat statbuf[3];
- ENTRY("write should change mtime/atime");
+ ENTER("write should change mtime/ctime");
+ snprintf(file, MAX_PATH_LENGTH, "%s/test_t18_file", lustre_path);
for (i = 0; i < 3; i++) {
fd = open(file, O_RDWR|O_CREAT|O_APPEND, (mode_t)0666);
if (fd < 0) {
printf("error open file: %s\n", strerror(errno));
- exit(-1);
+ return(-1);
}
if (write(fd, buf, sizeof(buf)) != sizeof(buf)) {
printf("error write file\n");
- exit(-1);
+ return(-1);
}
close(fd);
if(stat(file, &statbuf[i]) != 0) {
printf("Error stat\n");
- exit(1);
+ return(1);
}
- printf("mtime %ld, ctime %d\n",
- statbuf[i].st_atime, statbuf[i].st_mtime);
+ printf("ctime %lu, mtime %lu\n",
+ statbuf[i].st_ctime, statbuf[i].st_mtime);
sleep(2);
}
for (i = 1; i < 3; i++) {
- if ((statbuf[i].st_atime <= statbuf[i-1].st_atime) ||
+ if ((statbuf[i].st_ctime <= statbuf[i-1].st_ctime) ||
(statbuf[i].st_mtime <= statbuf[i-1].st_mtime)) {
printf("time error\n");
- exit(-1);
+ return(-1);
}
}
t_unlink(file);
+ LEAVE();
}
-#define PAGE_SIZE (4096)
-#define _npages (2048)
+int t18b(char *name)
+{
+ char file[MAX_PATH_LENGTH] = "";
+ int i;
+ struct stat statbuf[3];
+ ENTER("utime should change mtime/atime/ctime");
+ snprintf(file, MAX_PATH_LENGTH, "%s/test_t18b_file", lustre_path);
+ t_touch(file);
+
+ for (i = 0; i < 3; i++) {
+ t_utime(file, NULL);
+ if(stat(file, &statbuf[i]) != 0) {
+ printf("Error stat\n");
+ return(1);
+ }
+ printf("atime %lu, mtime %lu, ctime %lu\n",
+ statbuf[i].st_atime, statbuf[i].st_mtime,
+ statbuf[i].st_ctime);
+ sleep(2);
+ }
+
+ for (i = 1; i < 3; i++) {
+ if ((statbuf[i].st_atime <= statbuf[i-1].st_atime) ||
+ (statbuf[i].st_mtime <= statbuf[i-1].st_mtime) ||
+ (statbuf[i].st_ctime <= statbuf[i-1].st_ctime)) {
+ printf("time error\n");
+ return(-1);
+ }
+ }
+ t_unlink(file);
+ LEAVE();
+}
+
+static int check_file_size(char *file, long long size)
+{
+ struct stat statbuf;
+
+ if (stat(file, &statbuf) != 0) {
+ printf("Error stat(%s)\n", file);
+ return(1);
+ }
+ if (statbuf.st_size != size) {
+ printf("size of %s: %lld != %lld\n", file,
+ (long long)statbuf.st_size, (long long )size);
+ return(-1);
+ }
+ return 0;
+}
+
+int t19(char *name)
+{
+ char file[MAX_PATH_LENGTH] = "";
+ int fd;
+ int result;
+ ENTER("open(O_TRUNC) should truncate file to 0-length");
+ snprintf(file, MAX_PATH_LENGTH, "%s/test_t19_file", lustre_path);
+
+ t_echo_create(file, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
+
+ fd = open(file, O_RDWR|O_CREAT|O_TRUNC, (mode_t)0666);
+ if (fd < 0) {
+ printf("error open file: %s\n", strerror(errno));
+ return(-1);
+ }
+ close(fd);
+ result = check_file_size(file, 0);
+ if (result != 0)
+ return result;
+ t_unlink(file);
+ LEAVE();
+}
+
+int t20(char *name)
+{
+ char file[MAX_PATH_LENGTH] = "";
+ int fd;
+ struct iovec iov[2];
+ char buf[100];
+ long ret;
+ ENTER("trap app's general bad pointer for file i/o");
+ snprintf(file, MAX_PATH_LENGTH, "%s/test_t20_file", lustre_path);
+
+ fd = open(file, O_RDWR|O_CREAT, (mode_t)0666);
+ if (fd < 0) {
+ printf("error open file: %s\n", strerror(errno));
+ return(-1);
+ }
+
+ ret = write(fd, NULL, 20);
+ if (ret != -1 || errno != EFAULT) {
+ printf("write 1: ret %lld, errno %d\n", (long long)ret, errno);
+ return(1);
+ }
+ ret = write(fd, (void *)-1, 20);
+ if (ret != -1 || errno != EFAULT) {
+ printf("write 2: ret %lld, errno %d\n", (long long)ret, errno);
+ return(1);
+ }
+ iov[0].iov_base = NULL;
+ iov[0].iov_len = 10;
+ iov[1].iov_base = (void *)-1;
+ iov[1].iov_len = 10;
+ ret = writev(fd, iov, 2);
+ if (ret != -1 || errno != EFAULT) {
+ printf("writev 1: ret %lld, errno %d\n", (long long)ret, errno);
+ return(1);
+ }
+ iov[0].iov_base = NULL;
+ iov[0].iov_len = 0;
+ iov[1].iov_base = buf;
+ iov[1].iov_len = sizeof(buf);
+ ret = writev(fd, iov, 2);
+ if (ret != sizeof(buf)) {
+ printf("writev 2: ret %lld, error %d\n", (long long)ret, errno);
+ return(1);
+ }
+ lseek(fd, 0, SEEK_SET);
+
+ ret = read(fd, NULL, 20);
+ if (ret != -1 || errno != EFAULT) {
+ printf("read 1: ret %lld, errno %d\n", (long long)ret, errno);
+ return(1);
+ }
+ ret = read(fd, (void *)-1, 20);
+ if (ret != -1 || errno != EFAULT) {
+ printf("read 2: ret %lld, error %d\n", (long long)ret, errno);
+ return(1);
+ }
+ iov[0].iov_base = NULL;
+ iov[0].iov_len = 10;
+ iov[1].iov_base = (void *)-1;
+ iov[1].iov_len = 10;
+ ret = readv(fd, iov, 2);
+ if (ret != -1 || errno != EFAULT) {
+ printf("readv 1: ret %lld, error %d\n", (long long)ret, errno);
+ return(1);
+ }
+ iov[0].iov_base = NULL;
+ iov[0].iov_len = 0;
+ iov[1].iov_base = buf;
+ iov[1].iov_len = sizeof(buf);
+ ret = readv(fd, iov, 2);
+ if (ret != sizeof(buf)) {
+ printf("readv 2: ret %lld, error %d\n", (long long)ret, errno);
+ return(1);
+ }
+
+ close(fd);
+ t_unlink(file);
+ LEAVE();
+}
+
+int t21(char *name)
+{
+ char file[MAX_PATH_LENGTH] = "";
+ int fd, ret;
+ struct flock lock = {
+ .l_type = F_RDLCK,
+ .l_whence = SEEK_SET,
+ };
+
+ ENTER("basic fcntl support");
+ snprintf(file, MAX_PATH_LENGTH, "%s/test_t21_file", lustre_path);
+
+ fd = open(file, O_RDWR|O_CREAT, (mode_t)0666);
+ if (fd < 0) {
+ printf("error open file: %s\n", file);
+ return(-1);
+ }
+
+ t_fcntl(fd, F_SETFL, O_APPEND);
+ if (!(ret = t_fcntl(fd, F_GETFL)) & O_APPEND) {
+ printf("error get flag: ret %x\n", ret);
+ return(-1);
+ }
+
+ t_fcntl(fd, F_SETLK, &lock);
+ t_fcntl(fd, F_GETLK, &lock);
+ lock.l_type = F_WRLCK;
+ t_fcntl(fd, F_SETLKW, &lock);
+ t_fcntl(fd, F_GETLK, &lock);
+ lock.l_type = F_UNLCK;
+ t_fcntl(fd, F_SETLK, &lock);
+
+ close(fd);
+ t_unlink(file);
+ LEAVE();
+}
+
+int t22(char *name)
+{
+ char file[MAX_PATH_LENGTH] = "";
+ int fd;
+ char *str = "1234567890";
+ char buf[100];
+ long ret;
+ ENTER("make sure O_APPEND take effect");
+ snprintf(file, MAX_PATH_LENGTH, "%s/test_t22_file", lustre_path);
+
+ fd = open(file, O_TRUNC|O_RDWR|O_CREAT|O_APPEND, (mode_t)0666);
+ if (fd < 0) {
+ printf("error open file: %s\n", strerror(errno));
+ return(-1);
+ }
+
+ lseek(fd, 100, SEEK_SET);
+ ret = write(fd, str, strlen(str));
+ if (ret != strlen(str)) {
+ printf("write 1: ret %lld, errno %d\n", (long long)ret, errno);
+ return(1);
+ }
+
+ lseek(fd, 0, SEEK_SET);
+ ret = read(fd, buf, sizeof(buf));
+ if (ret != strlen(str)) {
+ printf("read 1: ret %lld\n", (long long)ret);
+ return(1);
+ }
+
+ if (memcmp(buf, str, strlen(str))) {
+ printf("read 1 data err\n");
+ return(1);
+ }
+
+ if (fcntl(fd, F_SETFL, 0)) {
+ printf("fcntl err: %s\n", strerror(errno));
+ return(1);
+ }
+
+ lseek(fd, 100, SEEK_SET);
+ ret = write(fd, str, strlen(str));
+ if (ret != strlen(str)) {
+ printf("write 2: ret %lld, errno %d\n", (long long)ret, errno);
+ return(1);
+ }
+
+ lseek(fd, 100, SEEK_SET);
+ ret = read(fd, buf, sizeof(buf));
+ if (ret != strlen(str)) {
+ printf("read 2: ret %lld\n", (long long)ret);
+ return(1);
+ }
+
+ if (memcmp(buf, str, strlen(str))) {
+ printf("read 2 data err\n");
+ return(1);
+ }
+
+ close(fd);
+ t_unlink(file);
+ LEAVE();
+}
+
+int t23(char *name)
+{
+ char path[MAX_PATH_LENGTH];
+ int fd;
+ long long ret;
+ loff_t off;
+
+ ENTER("handle seek > 2GB");
+ snprintf(path, MAX_PATH_LENGTH, "%s/f%s", lustre_path, name);
+
+ fd = open(path, O_WRONLY | O_CREAT | O_LARGEFILE, 0666);
+ if (fd < 0) {
+ printf("failed to create file %s: %s\n", path, strerror(errno));
+ return(-1);
+ }
+
+ off = 2048ULL * 1024 * 1024 - buf_size / 2;
+ ret = lseek(fd, off, SEEK_SET);
+ if (ret != off) {
+ printf("seek error for initial %llu != %llu\n",
+ ret, (long long)off);
+ return -1;
+ }
+
+ ret = write(fd, buf_alloc, buf_size);
+ if (ret != buf_size) {
+ printf("write error for %d != %llubytes @ %llu\n",
+ buf_size, ret, (long long)off);
+ if (ret == -1)
+ perror("write");
+ return -1;
+ }
+
+ ret = lseek(fd, off, SEEK_SET);
+ if (ret != off) {
+ printf("seek < 2GB error for %llu != %llu\n",
+ ret, (long long)off);
+ if (ret == -1)
+ perror("seek < 2GB");
+ return -1;
+ }
+
+ ret = lseek(fd, off + buf_size - 2, SEEK_SET);
+ if (ret != off + buf_size - 2) {
+ printf("seek > 2GB error for %llu != %llu\n",
+ ret, (long long)off);
+ if (ret == -1)
+ perror("seek > 2GB");
+ return -1;
+ }
-static int _buffer[_npages][PAGE_SIZE/sizeof(int)];
+ ret = lseek(fd, -buf_size + 2, SEEK_CUR);
+ if (ret != off) {
+ printf("relative seek error for %d %llu != %llu\n",
+ -buf_size + 2, ret, (unsigned long long) off);
+ if (ret == -1)
+ perror("relative seek");
+ return -1;
+ }
+
+ ret = lseek(fd, 0, SEEK_END);
+ if (ret != off + buf_size) {
+ printf("end seek error for %llu != %llu\n",
+ ret, (long long)off + buf_size);
+ if (ret == -1)
+ perror("end seek");
+ return -1;
+ }
+
+ ret = lseek(fd, 0, SEEK_SET);
+ if (ret != 0) {
+ printf("seek 0 error for %llu != 0\n", ret);
+ if (ret == -1)
+ perror("seek 0");
+ return -1;
+ }
+
+ off = 2048ULL * 1024 * 1024, SEEK_SET;
+ ret = lseek(fd, off, SEEK_SET);
+ if (ret != off) {
+ printf("seek 2GB error for %llu != %llu\n", ret, (unsigned long long) off);
+ if (ret == -1)
+ perror("seek 2GB");
+ return -1;
+ }
+
+ close(fd);
+ t_unlink(path);
+ LEAVE();
+}
/* pos: i/o start from
* xfer: npages per transfer
*/
-static void pages_io(int xfer, loff_t pos)
+static int pages_io(int xfer, loff_t pos)
{
- char *path="/mnt/lustre/test_t50";
- int check_sum[_npages] = {0,};
- int fd, rc, i, j;
+ char path[MAX_PATH_LENGTH] = "";
+
+ int check_sum[_npages] = {0,}, *buf;
+ int fd, rc, i, j, data_error = 0;
struct timeval tw1, tw2, tr1, tr2;
double tw, tr;
+ loff_t ret;
+
+ snprintf(path, MAX_PATH_LENGTH, "%s/test_t50", lustre_path);
- memset(_buffer, 0, sizeof(_buffer));
+ memset(buf_alloc, 0, buf_size);
/* create sample data */
- for (i = 0; i < _npages; i++) {
- for (j = 0; j < PAGE_SIZE/sizeof(int); j++) {
- _buffer[i][j] = rand();
+ for (i = 0, buf = buf_alloc; i < _npages; i++) {
+ for (j = 0; j < CFS_PAGE_SIZE/sizeof(int); j++, buf++) {
+ *buf = rand();
}
}
/* compute checksum */
- for (i = 0; i < _npages; i++) {
- for (j = 0; j < PAGE_SIZE/sizeof(int); j++) {
- check_sum[i] += _buffer[i][j];
+ for (i = 0, buf = buf_alloc; i < _npages; i++) {
+ for (j = 0; j < CFS_PAGE_SIZE/sizeof(int); j++, buf++) {
+ check_sum[i] += *buf;
}
}
+ unlink(path);
t_touch(path);
- fd = t_open(path);
+ fd = t_open(path);
/* write */
- lseek(fd, pos, SEEK_SET);
+ ret = lseek(fd, pos, SEEK_SET);
+ if (ret != pos) {
+ perror("write seek");
+ return 1;
+ }
gettimeofday(&tw1, NULL);
- for (i = 0; i < _npages; i += xfer) {
- rc = write(fd, _buffer[i], PAGE_SIZE * xfer);
- if (rc != PAGE_SIZE * xfer) {
- printf("write error %d (i = %d)\n", rc, i);
- exit(1);
+ for (i = 0, buf = buf_alloc; i < _npages;
+ i += xfer, buf += xfer * CFS_PAGE_SIZE / sizeof(int)) {
+ rc = write(fd, buf, CFS_PAGE_SIZE * xfer);
+ if (rc != CFS_PAGE_SIZE * xfer) {
+ printf("write error (i %d, rc %d): %s\n", i, rc,
+ strerror(errno));
+ return(1);
}
- }
+ }
gettimeofday(&tw2, NULL);
- memset(_buffer, 0, sizeof(_buffer));
+ memset(buf_alloc, 0, buf_size);
/* read */
- lseek(fd, pos, SEEK_SET);
+ ret = lseek(fd, pos, SEEK_SET);
+ if (ret != pos) {
+ perror("read seek");
+ return 1;
+ }
gettimeofday(&tr1, NULL);
- for (i = 0; i < _npages; i += xfer) {
- rc = read(fd, _buffer[i], PAGE_SIZE * xfer);
- if (rc != PAGE_SIZE * xfer) {
- printf("read error %d (i = %d)\n", rc, i);
- exit(1);
+ for (i = 0, buf = buf_alloc; i < _npages;
+ i += xfer, buf += xfer * CFS_PAGE_SIZE / sizeof(int)) {
+ rc = read(fd, buf, CFS_PAGE_SIZE * xfer);
+ if (rc != CFS_PAGE_SIZE * xfer) {
+ printf("read error (i %d, rc %d): %s\n", i, rc,
+ strerror(errno));
+ return(1);
}
- }
+ }
gettimeofday(&tr2, NULL);
/* compute checksum */
- for (i = 0; i < _npages; i++) {
+ for (i = 0, buf = buf_alloc; i < _npages; i++) {
int sum = 0;
- for (j = 0; j < PAGE_SIZE/sizeof(int); j++) {
- sum += _buffer[i][j];
+ for (j = 0; j < CFS_PAGE_SIZE/sizeof(int); j++, buf++) {
+ sum += *buf;
}
if (sum != check_sum[i]) {
- printf("chunk %d checksum error: expected 0x%x, get 0x%x\n",
+ data_error = 1;
+ printf("chunk %d checksum error expected %#x got %#x\n",
i, check_sum[i], sum);
}
}
- t_close(fd);
+ t_close(fd);
t_unlink(path);
tw = (tw2.tv_sec - tw1.tv_sec) * 1000000 + (tw2.tv_usec - tw1.tv_usec);
tr = (tr2.tv_sec - tr1.tv_sec) * 1000000 + (tr2.tv_usec - tr1.tv_usec);
printf(" (R:%.3fM/s, W:%.3fM/s)\n",
- (_npages * PAGE_SIZE) / (tw / 1000000.0) / (1024 * 1024),
- (_npages * PAGE_SIZE) / (tr / 1000000.0) / (1024 * 1024));
+ (_npages * CFS_PAGE_SIZE) / (tw / 1000000.0) / (1024 * 1024),
+ (_npages * CFS_PAGE_SIZE) / (tr / 1000000.0) / (1024 * 1024));
+
+ if (data_error)
+ return 1;
+
+ return 0;
}
-void t50()
+int t50(char *name)
{
- char text[256];
- loff_t off_array[] = {1, 17, 255, 258, 4095, 4097, 8191, 1024*1024*1024*1024ULL};
- int np = 1, i;
+ int np = 1;
loff_t offset = 0;
- ENTRY("4k aligned i/o sanity");
+ ENTER("4k aligned i/o sanity");
while (np <= _npages) {
printf("%3d per xfer(total %d)...\t", np, _npages);
- pages_io(np, offset);
+ fflush(stdout);
+ if (pages_io(np, offset) != 0)
+ return 1;
np += np;
}
LEAVE();
+}
- ENTRY("4k un-aligned i/o sanity");
+int t50b(char *name)
+{
+ loff_t off_array[] = {1, 17, 255, 258, 4095, 4097, 8191,
+ 1024*1024*1024*1024ULL};
+ int i;
+ long long offset;
+
+ ENTER("4k un-aligned i/o sanity");
for (i = 0; i < sizeof(off_array)/sizeof(loff_t); i++) {
offset = off_array[i];
printf("16 per xfer(total %d), offset %10lld...\t",
_npages, offset);
- pages_io(16, offset);
+ if (pages_io(16, offset) != 0)
+ return 1;
+ }
+
+ LEAVE();
+}
+
+enum {
+ T51_STEP = 42,
+ T51_NR = 1000
+};
+
+/*
+ * truncate(2) checks.
+ */
+int t51(char *name)
+{
+ char file[MAX_PATH_LENGTH] = "";
+ int fd;
+ long long size;
+ int result;
+
+ ENTER("truncate() should truncate file to proper length");
+ snprintf(file, MAX_PATH_LENGTH, "%s/test_t51_file", lustre_path);
+
+ for (size = 0; size < T51_NR * T51_STEP; size += T51_STEP) {
+ t_echo_create(file, "");
+ if (truncate(file, size) != 0) {
+ printf("\nerror truncating file: %s\n",strerror(errno));
+ return(-1);
+ }
+ result = check_file_size(file, size);
+ if (result != 0)
+ return result;
+ t_unlink(file);
+
+ t_echo_create(file, "");
+ fd = open(file, O_RDWR|O_CREAT, (mode_t)0666);
+ if (fd < 0) {
+ printf("\nerror open file: %s\n", strerror(errno));
+ return(-1);
+ }
+ if (ftruncate(fd, size) != 0) {
+ printf("\nerror ftruncating file:%s\n",strerror(errno));
+ return(-1);
+ }
+ close(fd);
+ result = check_file_size(file, size);
+ if (result != 0)
+ return result;
+ t_unlink(file);
+ if (size % (T51_STEP * (T51_NR / 75)) == 0) {
+ printf(".");
+ fflush(stdout);
+ }
+ }
+ printf("\n");
+ LEAVE();
+}
+/*
+ * check atime update during read
+ */
+int t52(char *name)
+{
+ char file[MAX_PATH_LENGTH] = "";
+ char buf[16];
+ struct stat statbuf;
+ time_t atime;
+ time_t diff;
+ int fd, i;
+
+ ENTER("atime should be updated during read");
+ snprintf(file, MAX_PATH_LENGTH, "%s/test_t52_file", lustre_path);
+
+ t_echo_create(file, "check atime update during read");
+ fd = open(file, O_RDONLY);
+ if (fd < 0) {
+ printf("\nerror open file: %s\n", strerror(errno));
+ return(-1);
+ }
+ stat(file, &statbuf);
+ printf("st_atime=%s", ctime(&statbuf.st_atime));
+ atime = statbuf.st_atime;
+ for (i = 0; i < 3; i++) {
+ ssize_t num_read;
+ sleep(2);
+ /* should not ignore read(2)'s return value */
+ num_read = read(fd, buf, sizeof(buf));
+ if (num_read < 0 ) {
+ printf("read from %s: %s\n", file, strerror(errno));
+ return -1;
+ }
+ stat(file, &statbuf);
+ printf("st_atime=%s", ctime(&statbuf.st_atime));
+ diff = statbuf.st_atime - atime;
+ if (diff <= 0) {
+ printf("atime doesn't updated! failed!\n");
+ close(fd);
+ t_unlink(file);
+ return -1;
+ }
+ atime = statbuf.st_atime;
+ }
+ close(fd);
+ t_unlink(file);
+ LEAVE();
+}
+
+#define NEW_TIME 10000
+int t53(char *name)
+{
+ char file[MAX_PATH_LENGTH] = "";
+ struct utimbuf times; /* struct. buffer for utime() */
+ struct stat stat_buf; /* struct buffer to hold file info. */
+ time_t mtime, atime;
+
+ ENTER("mtime/atime should be updated by utime() call");
+ snprintf(file, MAX_PATH_LENGTH, "%s/test_t53_file", lustre_path);
+
+ t_echo_create(file, "check mtime/atime update by utime() call");
+
+ /* Initialize the modification and access time in the times arg */
+ times.actime = NEW_TIME+10;
+ times.modtime = NEW_TIME;
+
+ /* file modification/access time */
+ utime(file, ×);
+
+ if (stat(file, &stat_buf) < 0) {
+ printf("stat(2) of %s failed, error:%d %s\n",
+ file, errno, strerror(errno));
+ }
+ mtime = stat_buf.st_mtime;
+ atime = stat_buf.st_atime;
+
+ if ((mtime == NEW_TIME) && (atime == NEW_TIME + 10)) {
+ t_unlink(file);
+ LEAVE();
+ }
+
+ printf("mod time %ld, expected %ld\n", mtime, (long)NEW_TIME);
+ printf("acc time %ld, expected %ld\n", atime, (long)NEW_TIME + 10);
+
+ t_unlink(file);
+ return (-1);
+}
+
+int t54(char *name)
+{
+ char file[MAX_PATH_LENGTH] = "";
+ struct flock lock;
+ int fd, err;
+
+ ENTER("fcntl should return 0 when succeed in getting flock");
+ snprintf(file, MAX_PATH_LENGTH, "%s/test_t54_file", lustre_path);
+
+ t_echo_create(file, "fcntl should return 0 when succeed");
+
+ fd = open(file, O_RDWR);
+ if (fd < 0) {
+ printf("\nerror open file: %s\n", strerror(errno));
+ return(-1);
+ }
+ lock.l_type = F_WRLCK;
+ lock.l_start = 0;
+ lock.l_whence = 0;
+ lock.l_len = 1;
+ if ((err = t_fcntl(fd, F_SETLKW, &lock)) != 0) {
+ fprintf(stderr, "fcntl returned: %d (%s)\n",
+ err, strerror(err));
+ close(fd);
+ t_unlink(file);
+ return (-1);
}
+
+ lock.l_type = F_UNLCK;
+ t_fcntl(fd, F_SETLKW, &lock);
+ close(fd);
+ t_unlink(file);
+ LEAVE();
+}
+
+/* for O_DIRECTORY */
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+#define STRIPE_SIZE (2048 * 2048)
+#define STRIPE_OFFSET 0
+#define STRIPE_COUNT 1
+int t55(char *name)
+{
+ char path[MAX_PATH_LENGTH] = "";
+ char file[MAX_PATH_LENGTH] = "";
+ struct lov_user_md *lum = NULL;
+ struct lov_user_ost_data *lo = NULL;
+ int index, fd, buflen, rc;
+
+ ENTER("setstripe/getstripe");
+ snprintf(path, MAX_PATH_LENGTH, "%s/test_t55", lustre_path);
+ snprintf(file, MAX_PATH_LENGTH, "%s/test_t55/file_t55", lustre_path);
+
+ buflen = sizeof(struct lov_user_md);
+ buflen += STRIPE_COUNT * sizeof(struct lov_user_ost_data);
+ lum = (struct lov_user_md *)malloc(buflen);
+ if (!lum) {
+ printf("out of memory!\n");
+ return -1;
+ }
+ memset(lum, 0, buflen);
+
+ t_mkdir(path);
+ rc = llapi_file_create(path, STRIPE_SIZE, STRIPE_OFFSET,
+ STRIPE_COUNT, LOV_PATTERN_RAID0);
+ if (rc) {
+ printf("llapi_file_create failed: rc = %d (%s) \n",
+ rc, strerror(-rc));
+ t_rmdir(path);
+ free(lum);
+ return -1;
+ }
+
+ fd = open(file, O_CREAT | O_RDWR, 0644);
+ if (fd < 0) {
+ printf("open file(%s) failed: rc = %d (%s) \n)",
+ file, fd, strerror(errno));
+ t_rmdir(path);
+ free(lum);
+ return -1;
+ }
+
+ lum->lmm_magic = LOV_USER_MAGIC;
+ lum->lmm_stripe_count = STRIPE_COUNT;
+ rc = ioctl(fd, LL_IOC_LOV_GETSTRIPE, lum);
+ if (rc) {
+ printf("dir:ioctl(LL_IOC_LOV_GETSTRIPE) failed: rc = %d(%s)\n",
+ rc, strerror(errno));
+ close(fd);
+ t_unlink(file);
+ t_rmdir(path);
+ free(lum);
+ return -1;
+ }
+
+ close(fd);
+
+ if (opt_verbose) {
+ printf("lmm_magic: 0x%08X\n", lum->lmm_magic);
+ printf("lmm_object_id: "LPX64"\n", lum->lmm_object_id);
+ printf("lmm_object_seq: "LPX64"\n", lum->lmm_object_seq);
+ printf("lmm_stripe_count: %u\n", (int)lum->lmm_stripe_count);
+ printf("lmm_stripe_size: %u\n", lum->lmm_stripe_size);
+ printf("lmm_stripe_pattern: %x\n", lum->lmm_pattern);
+
+ for (index = 0; index < lum->lmm_stripe_count; index++) {
+ lo = lum->lmm_objects + index;
+ printf("object %d:\n", index);
+ printf("\tobject_seq: "LPX64"\n", lo->l_object_seq);
+ printf("\tobject_id: "LPX64"\n", lo->l_object_id);
+ printf("\tost_gen: %#x\n", lo->l_ost_gen);
+ printf("\tost_idx: %u\n", lo->l_ost_idx);
+ }
+ }
+
+ if (lum->lmm_magic != LOV_USER_MAGIC ||
+ lum->lmm_pattern != LOV_PATTERN_RAID0 ||
+ lum->lmm_stripe_size != STRIPE_SIZE ||
+ lum->lmm_objects[0].l_ost_idx != STRIPE_OFFSET ||
+ lum->lmm_stripe_count != STRIPE_COUNT) {
+ printf("incorrect striping information!\n");
+ t_unlink(file);
+ t_rmdir(path);
+ free(lum);
+ return -1;
+ }
+ t_unlink(file);
+
+ /* setstripe on regular file */
+ rc = llapi_file_create(file, STRIPE_SIZE, STRIPE_OFFSET,
+ STRIPE_COUNT, LOV_PATTERN_RAID0);
+ if (rc) {
+ printf("llapi_file_create failed: rc = %d (%s) \n",
+ rc, strerror(-rc));
+ t_unlink(file);
+ t_rmdir(path);
+ free(lum);
+ return -1;
+ }
+ fd = open(file, O_RDWR, 0644);
+ if (fd < 0) {
+ printf("failed to open(%s): rc = %d (%s)\n",
+ file, fd, strerror(errno));
+ t_unlink(file);
+ t_rmdir(path);
+ free(lum);
+ return -1;
+ }
+
+ lum->lmm_magic = LOV_USER_MAGIC;
+ lum->lmm_stripe_count = STRIPE_COUNT;
+ rc = ioctl(fd, LL_IOC_LOV_GETSTRIPE, lum);
+ if (rc) {
+ printf("file:ioctl(LL_IOC_LOV_GETSTRIPE) failed: rc = %d(%s)\n",
+ rc, strerror(errno));
+ close(fd);
+ t_unlink(file);
+ t_rmdir(path);
+ free(lum);
+ return -1;
+ }
+ close(fd);
+
+ if (opt_verbose) {
+ printf("lmm_magic: 0x%08X\n", lum->lmm_magic);
+ printf("lmm_object_id: "LPX64"\n", lum->lmm_object_id);
+ printf("lmm_object_seq: "LPX64"\n", lum->lmm_object_seq);
+ printf("lmm_stripe_count: %u\n", (int)lum->lmm_stripe_count);
+ printf("lmm_stripe_size: %u\n", lum->lmm_stripe_size);
+ printf("lmm_stripe_pattern: %x\n", lum->lmm_pattern);
+
+ for (index = 0; index < lum->lmm_stripe_count; index++) {
+ lo = lum->lmm_objects + index;
+ printf("object %d:\n", index);
+ printf("\tobject_seq: "LPX64"\n", lo->l_object_seq);
+ printf("\tobject_id: "LPX64"\n", lo->l_object_id);
+ printf("\tost_gen: %#x\n", lo->l_ost_gen);
+ printf("\tost_idx: %u\n", lo->l_ost_idx);
+ }
+ }
+
+ if (lum->lmm_magic != LOV_USER_MAGIC ||
+ lum->lmm_pattern != LOV_PATTERN_RAID0 ||
+ lum->lmm_stripe_size != STRIPE_SIZE ||
+ lum->lmm_objects[0].l_ost_idx != STRIPE_OFFSET ||
+ lum->lmm_stripe_count != STRIPE_COUNT) {
+ printf("incorrect striping information!\n");
+ t_unlink(file);
+ t_rmdir(path);
+ free(lum);
+ return -1;
+ }
+
+ t_unlink(file);
+ t_rmdir(path);
+ free(lum);
+ LEAVE();
+}
+
+/*
+ * getdirentries should return -1 and set errno to EINVAL when the size
+ * specified as an argument is too small to contain at least one entry
+ * (see bugzilla ticket 12229)
+ */
+int t56(char *name)
+{
+ int fd;
+ size_t nbytes;
+ off_t basep = 0;
+ long rc = 0;
+ cfs_dirent_t dir;
+
+ ENTER("getdirentries should fail if nbytes is too small");
+
+ /* Set count to be very small. The result should be EINVAL */
+ nbytes = 8;
+
+ /* open the directory and call getdirentries */
+ fd = t_opendir(lustre_path);
+
+ rc = getdirentries(fd, (char *)&dir, nbytes, &basep);
+
+ if (rc != -1) {
+ printf("Test failed: getdirentries returned %lld\n",
+ (long long)rc);
+ t_close(fd);
+ return -1;
+ }
+ if (errno != EINVAL) {
+ printf("Test failed: getdirentries returned %lld but errno is "
+ "set to %d (should be EINVAL)\n", (long long)rc, errno);
+ t_close(fd);
+ return -1;
+ }
+ t_close(fd);
+
LEAVE();
}
extern void __liblustre_setup_(void);
extern void __liblustre_cleanup_(void);
+
void usage(char *cmd)
{
- printf("Usage: \t%s --target mdsnid:/mdsname/profile\n", cmd);
- printf(" \t%s --dumpfile dumpfile\n", cmd);
+ printf("\n"
+ "usage: %s [-o test][-e test][-v] --target mgsnid:/fsname\n",
+ cmd);
+ printf(" %s --dumpfile dumpfile\n", cmd);
exit(-1);
}
+struct testlist {
+ int (*test)(char *name);
+ char *name;
+} testlist[] = {
+ { t1, "1" },
+ { t2, "2" },
+ { t3, "3" },
+ { t4, "4" },
+ { t6, "6" },
+ { t6b, "6b" },
+ { t7, "7" },
+ { t8, "8" },
+ { t9, "9" },
+ { t10, "10" },
+ { t11, "11" },
+ { t12, "12" },
+ { t13, "13" },
+ { t14, "14" },
+ { t15, "15" },
+ { t16, "16" },
+ { t17, "17" },
+ { t18, "18" },
+ { t18b, "t8b" },
+ { t19, "19" },
+ { t20, "20" },
+ { t21, "21" },
+ { t22, "22" },
+ { t23, "23" },
+ { t50, "50" },
+ { t50b, "50b" },
+ { t51, "51" },
+ { t53, "53" },
+ { t54, "54" },
+ { t55, "55" },
+ { t56, "56" },
+ { NULL, NULL }
+};
+
int main(int argc, char * const argv[])
{
- int opt_index, c;
+ struct testlist *test;
+ int opt_index, c, rc = 0, numonly = 0, numexcept = 0;
+ char *only[100], *except[100];
static struct option long_opts[] = {
- {"target", 1, 0, 0},
- {"dumpfile", 1, 0, 0},
+ {"dumpfile", 1, 0, 'd'},
+ {"only", 1, 0, 'o'},
+ {"except", 1, 0, 'e'},
+ {"target", 1, 0, 't'},
+ {"verbose", 1, 0, 'v'},
{0, 0, 0, 0}
};
- if (argc <= 1)
- usage(argv[0]);
-
- while ((c = getopt_long(argc, argv, "", long_opts, &opt_index)) != -1) {
+ while ((c = getopt_long(argc, argv, "d:e:o:t:v", long_opts, &opt_index)) != -1) {
switch (c) {
- case 0: {
- if (!optarg[0])
- usage(argv[0]);
-
- if (!strcmp(long_opts[opt_index].name, "target")) {
- setenv(ENV_LUSTRE_MNTTGT, optarg, 1);
- } else if (!strcmp(long_opts[opt_index].name, "dumpfile")) {
- setenv(ENV_LUSTRE_DUMPFILE, optarg, 1);
- } else
- usage(argv[0]);
+ case 'd':
+ setenv(ENV_LUSTRE_DUMPFILE, optarg, 1);
+ break;
+ case 'e':
+ if (numexcept == 0)
+ printf("Not running test(s): ");
+ printf("%s ", optarg);
+ except[numexcept++] = optarg;
+ break;
+ case 'o':
+ if (numonly == 0)
+ printf("Only running test(s): ");
+ printf("%s ", optarg);
+ only[numonly++] = optarg;
+ break;
+ case 't':
+ setenv(ENV_LUSTRE_MNTTGT, optarg, 1);
+ break;
+ case 'v':
+ opt_verbose++;
break;
- }
default:
usage(argv[0]);
+ break;
}
}
+ if (getenv(ENV_LUSTRE_MNTTGT) == NULL &&
+ getenv(ENV_LUSTRE_DUMPFILE) == NULL)
+ usage(argv[0]);
+
if (optind != argc)
usage(argv[0]);
+ printf("\n");
+
__liblustre_setup_();
- t1();
- t2();
- t3();
- t4();
- t6();
- t7();
- t8();
- t9();
- t10();
- t11();
- t12();
- t13();
- t14();
- t15();
- t16();
- t17();
- t18();
- t50();
-
- printf("liblustre is about shutdown\n");
+ buf_size = _npages * CFS_PAGE_SIZE;
+ if (opt_verbose)
+ printf("allocating %d bytes buffer\n", buf_size);
+ buf_alloc = calloc(1, buf_size);
+ if (buf_alloc == NULL) {
+ fprintf(stderr, "error allocating %d\n", buf_size);
+ exit(-ENOMEM);
+ }
+
+ for (test = testlist; test->test != NULL; test++) {
+ int run = 1, i;
+ int len, olen;
+
+ if (numexcept > 0) {
+ len = strlen(test->name);
+ for (i = 0; i < numexcept; i++) {
+ olen = strlen(except[i]);
+
+ if (len < olen)
+ continue;
+
+ if (strncmp(except[i], test->name, olen) == 0) {
+ switch(test->name[olen]) {
+ case '0': case '1': case '2': case '3':
+ case '4': case '5': case '6': case '7':
+ case '8': case '9':
+ break;
+ default:
+ run = 0;
+ break;
+ }
+ }
+ }
+ }
+
+ if (numonly > 0) {
+ run = 0;
+ len = strlen(test->name);
+ for (i = 0; i < numonly; i++) {
+ olen = strlen(only[i]);
+
+ if (len < olen)
+ continue;
+
+ if (strncmp(only[i], test->name, olen) == 0) {
+ switch(test->name[olen]) {
+ case '0': case '1': case '2': case '3':
+ case '4': case '5': case '6': case '7':
+ case '8': case '9':
+ break;
+ default:
+ run = 1;
+ break;
+ }
+ }
+ }
+ }
+ if (run && (rc = (test->test)(test->name)) != 0)
+ break;
+ }
+
+ free(buf_alloc);
+
+ printf("liblustre is about to shutdown\n");
__liblustre_cleanup_();
- printf("complete successfully\n");
- return 0;
+ printf("complete successfully\n");
+ return rc;
}