# --enable-mpitest
#
AC_ARG_ENABLE(mpitests,
- AC_HELP_STRING([--enable-mpitest=yes|no|mpich directory],
+ AC_HELP_STRING([--enable-mpitests=yes|no|mpicc wrapper],
[include mpi tests]),
[
enable_mpitests=yes
case $enableval in
yes)
- MPI_ROOT=/opt/mpich
- LDFLAGS="$LDFLAGS -L$MPI_ROOT/ch-p4/lib -L$MPI_ROOT/ch-p4/lib64"
- CFLAGS="$CFLAGS -I$MPI_ROOT/include"
+ MPICC_WRAPPER=mpicc
;;
no)
enable_mpitests=no
;;
- [[\\/$]]* | ?:[[\\/]]* )
- MPI_ROOT=$enableval
- LDFLAGS="$LDFLAGS -L$with_mpi/lib"
- CFLAGS="$CFLAGS -I$MPI_ROOT/include"
- ;;
*)
- AC_MSG_ERROR([expected absolute directory name for --enable-mpitests or yes or no])
+ MPICC_WRAPPER=$enableval
;;
esac
],
[
- MPI_ROOT=/opt/mpich
- LDFLAGS="$LDFLAGS -L$MPI_ROOT/ch-p4/lib -L$MPI_ROOT/ch-p4/lib64"
- CFLAGS="$CFLAGS -I$MPI_ROOT/include"
+ MPICC_WRAPPER=mpicc
enable_mpitests=yes
]
)
-AC_SUBST(MPI_ROOT)
if test x$enable_mpitests != xno; then
- AC_MSG_CHECKING([whether to mpitests can be built])
- AC_CHECK_FILE([$MPI_ROOT/include/mpi.h],
- [AC_CHECK_LIB([mpich],[MPI_Start],[enable_mpitests=yes],[enable_mpitests=no])],
- [enable_mpitests=no])
+ AC_MSG_CHECKING([whether mpitests can be built])
+ oldcc=$CC
+ CC=$MPICC_WRAPPER
+ AC_LINK_IFELSE(
+ [AC_LANG_PROGRAM([[
+ #include <mpi.h>
+ ]],[[
+ int flag;
+ MPI_Initialized(&flag);
+ ]])],
+ [
+ AC_MSG_RESULT([yes])
+ ],[
+ AC_MSG_RESULT([no])
+ enable_mpitests=no
+ ])
+ CC=$oldcc
fi
-AC_MSG_RESULT([$enable_mpitests])
-
+AC_SUBST(MPICC_WRAPPER)
AC_MSG_NOTICE([Enabling Lustre configure options for libsysio])
ac_configure_args="$ac_configure_args --with-lustre-hack --with-sockets"
lustre/fid/autoMakefile
lustre/liblustre/Makefile
lustre/liblustre/tests/Makefile
+lustre/liblustre/tests/mpi/Makefile
lustre/llite/Makefile
lustre/llite/autoMakefile
lustre/lclient/Makefile
lustre/scripts/Makefile
lustre/scripts/version_tag.pl
lustre/tests/Makefile
+lustre/tests/mpi/Makefile
lustre/utils/Makefile
lustre/utils/gss/Makefile
])
noinst_LIBRARIES = libtestcommon.a
if LIBLUSTRE_TESTS
+if MPITESTS
+SUBDIRS = mpi
+endif # MPITESTS
+
noinst_PROGRAMS = sanity
if !CRAY_XT3
noinst_PROGRAMS += recovery_small replay_single replay_ost_single
endif # !CRAY_XT3
-if MPITESTS
-noinst_PROGRAMS += test_lock_cancel
-endif # MPITESTS
-
liblustre_testdir=$(libdir)/lustre/liblustre/tests
liblustre_test_PROGRAMS = $(noinst_PROGRAMS)
liblustre_test_LIBRARIES = $(noinst_LIBRARIES)
endif # LIBLUSTRE_TESTS
endif # LIBLUSTRE
+DIST_SUBDIRS := mpi
+
libtestcommon_a_SOURCES = test_common.c test_common.h
sanity_SOURCES = sanity.c
replay_ost_single_CFLAGS = $(LL_CFLAGS)
replay_ost_single_LDADD := libtestcommon.a $(LLIB_EXEC)
replay_ost_single_DEPENDENCIES = $(top_builddir)/lustre/liblustre/liblustre.a libtestcommon.a
-
-if MPITESTS
-test_lock_cancel_SOURCES = test_lock_cancel.c
-test_lock_cancel_CFLAGS = $(LL_CFLAGS) -I/opt/lam/include
-#test_lock_cancel_LDADD := $(LLIB_EXEC) -L/opt/lam/lib -lmpi -llam
-test_lock_cancel_LDADD := $(LLIB_EXEC) -lmpich
-endif
-
-
--- /dev/null
+## Liblustre MPI tests Makefile
+
+AM_CPPFLAGS = -I$(SYSIO)/include $(LLCPPFLAGS) -I$(top_srcdir)/lnet/ulnds
+AM_CFLAGS = $(LLCFLAGS)
+
+LLIB_EXEC = $(top_builddir)/lustre/utils/liblustreapi.a $(top_builddir)/lustre/liblustre/liblustre.a $(CAP_LIBS) $(PTHREAD_LIBS) $(ZLIB)
+
+CC = @MPICC_WRAPPER@
+
+if LIBLUSTRE
+if LIBLUSTRE_TESTS
+noinst_PROGRAMS = test_lock_cancel
+endif # LIBLUSTRE_TESTS
+endif # LIBLUSTRE
+
+test_lock_cancel_SOURCES = test_lock_cancel.c
+test_lock_cancel_LDADD := $(LLIB_EXEC)
#include <sysio.h>
#include <mount.h>
-#include <test_common.h>
+#include <../test_common.h>
#include <mpi.h>
# LDADD = -lldap
# LDADD := -lreadline -ltermcap # -lefence
+DIST_SUBDIRS := mpi
+
noinst_DATA = disk1_8.tar.bz2
noinst_SCRIPTS = leak_finder.pl llmount.sh llmountcleanup.sh functions.sh
noinst_SCRIPTS += test-framework.sh runvmstat runiozone runtests
$(nobase_noinst_SCRIPTS) $(nobase_noinst_DATA)
if TESTS
+if MPITESTS
+SUBDIRS = mpi
+endif
noinst_PROGRAMS = openunlink truncate directio writeme mlink utime it_test
noinst_PROGRAMS += tchmod fsx test_brw sendfile
noinst_PROGRAMS += createmany chownmany statmany multifstat createtest
noinst_PROGRAMS += openfilleddirunlink rename_many memhog iopentest1 iopentest2
noinst_PROGRAMS += mmap_sanity flock_test writemany reads flocks_test
noinst_PROGRAMS += ll_getstripe_info write_time_limit rwv
-if MPITESTS
-noinst_PROGRAMS += parallel_grouplock write_append_truncate createmany_mpi mdsrate
-endif
# noinst_PROGRAMS += copy_attr mkdirdeep
bin_PROGRAMS = mcreate munlink
testdir = $(libdir)/lustre/tests
flocks_test_SOURCES=flocks_test.c
flocks_test_LDADD=-lpthread
-if MPITESTS
-#LAM_LD_FLAGS=-L/opt/lam/lib -lmpi -llam -lpthread
-LAM_LD_FLAGS=-lmpich -lpthread
-write_append_truncate_SOURCES=write_append_truncate.c
-write_append_truncate_LDADD=$(LAM_LD_FLAGS)
-createmany_mpi_SOURCES=createmany-mpi.c
-createmany_mpi_LDADD=$(LAM_LD_FLAGS)
-parallel_grouplock_SOURCES=parallel_grouplock.c lp_utils.c lp_utils.h
-parallel_grouplock_LDADD=$(LAM_LD_FLAGS)
-mdsrate_SOURCES=mdsrate.c
-mdsrate_LDADD=$(LAM_LD_FLAGS) -L$(top_builddir)/lustre/utils -llustreapi
-endif
-
#copy_attr_LDADD= -lattr
--- /dev/null
+# Lustre MPI test Makefile
+AM_CPPFLAGS = $(LLCPPFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -DLUSTRE_UTILS
+AM_CFLAGS = $(LLCFLAGS)
+
+CC = @MPICC_WRAPPER@
+
+noinst_PROGRAMS = parallel_grouplock write_append_truncate createmany_mpi mdsrate
+testdir = $(libdir)/lustre/tests
+test_SCRIPTS = $(noinst_PROGRAMS)
+
+write_append_truncate_SOURCES=write_append_truncate.c
+createmany_mpi_SOURCES=createmany-mpi.c
+parallel_grouplock_SOURCES=parallel_grouplock.c lp_utils.c lp_utils.h
+mdsrate_SOURCES=mdsrate.c
+mdsrate_LDADD=-L$(top_builddir)/lustre/utils -llustreapi
--- /dev/null
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * 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 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).
+ *
+ * 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
+ *
+ * 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.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. 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/tests/lp_utils.c
+ *
+ * Author: You Feng <youfeng@clusterfs.com>
+ */
+
+#include <mpi.h>
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <liblustre.h>
+#include "lustre/lustre_user.h"
+#include "lustre/tests/mpi/lp_utils.h"
+
+#define MAX_PROCESSES 8
+
+int verbose = 0;
+int debug = 0;
+
+char hostname[1024];
+
+struct timeval t1, t2;
+
+char *timestamp() {
+ static char datestring[80];
+ time_t timestamp;
+
+ fflush(stdout);
+ timestamp = time(NULL);
+ strftime(datestring, 80, "%T", localtime(×tamp));
+
+ return datestring;
+}
+
+inline void begin(char *str) {
+ if (verbose > 0 && rank == 0) {
+ gettimeofday(&t1, NULL);
+ printf("%s:\tBeginning %s\n", timestamp(), str);
+ fflush(stdout);
+ }
+}
+
+inline void end(char *str) {
+ float elapsed;
+
+ MPI_Barrier(MPI_COMM_WORLD);
+ if (verbose > 0 && rank == 0) {
+ gettimeofday(&t2, NULL);
+ elapsed = (t2.tv_sec + ((float)t2.tv_usec/1000000))
+ - (t1.tv_sec + ((float)t1.tv_usec/1000000));
+ if (elapsed >= 60) {
+ printf("%s:\tFinished %-15s(%.2f min)\n",
+ timestamp(), str, elapsed / 60);
+ } else {
+ printf("%s:\tFinished %-15s(%.3f sec)\n",
+ timestamp(), str, elapsed);
+
+ }
+ fflush(stdout);
+ }
+}
+
+void dump_diff(char *orig_buf, char *buf, int size, long _off)
+{
+ int i, diff, off;
+ char *p, *end;
+
+ printf("commpared buf size %d, at offset %lu\n\n", size, _off);
+
+ if (orig_buf) {
+ printf("original buf:\n");
+ p = orig_buf;
+ end = orig_buf + size;
+ i = 1;
+ while (p < end) {
+ printf(" %8lx", *(long *)p);
+ p += sizeof(long);
+ if (i++%8 == 0)
+ printf("\n");
+ }
+ if (i%8) printf("\n\n");
+ else printf("\n");
+ }
+
+ if (buf) {
+ printf("different data: diff_data(orig_data)\n");
+ diff = 0;
+ off = 0;
+ i = 1;
+ p = buf;
+ end = buf + size;
+ while (p < end) {
+ if (memcmp(p, orig_buf + off, sizeof(long)) != 0) {
+ printf("\toff: %5d,\tdata: %8lx (%8lx)\n", off,
+ *(unsigned long *)p,
+ *(unsigned long *)(orig_buf + off));
+ diff++;
+ }
+ off += sizeof(long);
+ p += sizeof(long);
+ }
+ printf("\n %d total differents found\n\n", diff);
+ }
+}
+
+void lp_gethostname(void)
+{
+ if (gethostname(hostname, 1024) == -1) {
+ fprintf(stderr, "gethostname: (%d)%s", errno, strerror(errno));
+ MPI_Abort(MPI_COMM_WORLD, 2);
+ }
+}
+
+/* This function does not FAIL if the requested "name" does not exit.
+ * This is just to clean up any files or directories left over from
+ * previous runs
+ */
+void remove_file_or_dir(char *name)
+{
+ struct stat statbuf;
+ char errmsg[MAX_FILENAME_LEN + 20];
+
+ if (stat(name, &statbuf) != -1) {
+ if (S_ISREG(statbuf.st_mode)) {
+ printf("stale file found\n");
+ if (unlink(name) == -1) {
+ sprintf(errmsg, "unlink of %s", name);
+ FAIL(errmsg);
+ }
+ }
+ if (S_ISDIR(statbuf.st_mode)) {
+ printf("stale directory found\n");
+ if (rmdir(name) == -1) {
+ sprintf(errmsg, "rmdir of %s", name);
+ FAIL(errmsg);
+ }
+ }
+ }
+}
+
+void create_file(char *name, long filesize, int fill)
+{
+ static char filename[MAX_FILENAME_LEN];
+ char errmsg[MAX_FILENAME_LEN + 20];
+ char buf[1024 * 8];
+ char c = 'A' + size;
+ int fd, rc;
+ short zero = 0;
+ long left = filesize;
+
+ /* Process 0 creates the test file(s) */
+ if (rank == 0) {
+ sprintf(filename, "%s/%s", testdir, name);
+ remove_file_or_dir(filename);
+ if ((fd = creat(filename, FILEMODE)) == -1) {
+ sprintf(errmsg, "create of file %s", filename);
+ FAIL(errmsg);
+ }
+ if (filesize > 0) {
+ if (lseek(fd, filesize - 1, SEEK_SET) == -1) {
+ close(fd);
+ sprintf(errmsg, "lseek of file %s", filename);
+ FAIL(errmsg);
+ }
+ if (write(fd, &zero, 1) == -1) {
+ close(fd);
+ sprintf(errmsg, "write of file %s", filename);
+ FAIL(errmsg);
+ }
+ }
+ if (filesize > 0 && fill) {
+ if (lseek(fd, 0, SEEK_SET) == -1) {
+ close(fd);
+ sprintf(errmsg, "lseek of file %s", filename);
+ FAIL(errmsg);
+ }
+ memset(buf, c, 1024);
+ while (left > 0) {
+ if ((rc = write(fd, buf,
+ left > (1024 * 8) ? (1024 * 8) : left))
+ == -1) {
+ close(fd);
+ sprintf(errmsg, "write of file %s", filename);
+ FAIL(errmsg);
+ }
+ left -= rc;
+ }
+ }
+ if (close(fd) == -1) {
+ sprintf(errmsg, "close of file %s", filename);
+ FAIL(errmsg);
+ }
+ }
+}
+
+void check_stat(char *filename, struct stat *state, struct stat *old_state)
+{
+ char errmsg[MAX_FILENAME_LEN+20];
+
+ if (stat(filename, state) == -1) {
+ sprintf(errmsg, "stat of file %s", filename);
+ FAIL(errmsg);
+ }
+
+ if (memcmp(state, old_state, sizeof(struct stat)) != 0) {
+ errno = 0;
+ sprintf(errmsg, LP_STAT_FMT, LP_STAT_ARGS);
+ FAIL(errmsg);
+ }
+}
+
+void remove_file(char *name)
+{
+ char filename[MAX_FILENAME_LEN];
+ char errmsg[MAX_FILENAME_LEN + 20];
+
+ /* Process 0 remove the file(s) */
+ if (rank == 0) {
+ sprintf(filename, "%s/%s", testdir, name);
+ if (unlink(filename) == -1) {
+ sprintf(errmsg, "unlink of file %s", filename);
+ FAIL(errmsg);
+ }
+ }
+}
+
+void fill_stride(char *buf, int buf_size, long long rank, long long _off)
+{
+ char *p = buf;
+ long long off, data[2];
+ int cp, left = buf_size;
+
+ data[0] = rank;
+ off = _off;
+ while (left > 0) {
+ data[1] = off;
+ cp = left > sizeof(data) ? sizeof(data) : left;
+ memcpy(p, data, cp);
+ off += cp;
+ p += cp;
+ left -= cp;
+ }
+}
--- /dev/null
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * 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 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).
+ *
+ * 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
+ *
+ * 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.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. 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/tests/lp_utils.h
+ *
+ * Author: You Feng <youfeng@clusterfs.com>
+ */
+
+#ifndef __LP_UTILS_H__
+#define __LP_UTILS_H__
+
+#include "lustre/lustre_user.h"
+
+#define FAIL(msg) \
+ \
+do { \
+ printf("%s: Process %d (%s)\n", timestamp(), rank, hostname); \
+ if (debug) \
+ printf("\tFAILED in %s:%d:%s()\n", __FILE__, __LINE__, __func__); \
+ else \
+ printf("\tFAILED in %s()\n", __func__); \
+ printf("%s", msg); \
+ fflush(stdout); \
+ MPI_Abort(MPI_COMM_WORLD, 1); \
+} while(0)
+
+#define FILEMODE S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH
+#define MAX_FILENAME_LEN 512
+
+extern int verbose;
+extern int debug;
+
+extern int rank;
+extern int size;
+
+extern char hostname[];
+extern char *timestamp();
+extern char *testdir;
+
+extern inline void begin(char *str);
+extern inline void end(char *str);
+
+extern void dump_diff(char *orig_buf, char *buf, int len, long off);
+extern void lp_gethostname(void);
+
+extern void create_file(char *name, long filesize, int fill);
+extern void fill_file(char *name, long filesize);
+
+#define LP_STAT_FMT \
+ \
+"Stat error:\n \
+\tfields\t\tvalue\told value\n \
+\tst_dev\t\t%d\t%d\n \
+\tst_ino\t\t%d\t%d\n \
+\tst_mode\t\t%o\t%o\n \
+\tst_nlink\t%d\t%d\n \
+\tst_uid\t\t%d\t%d\n \
+\tst_gid\t\t%d\t%d\n \
+\tst_rdev\t\t%x.%x\t%x.%x\n \
+\tst_size\t\t%lu\t%lu\n \
+\tst_blksize\t%d\t%d\n \
+\tst_blocks\t%u\t%u\n \
+\tst_atime\t%d\t%d\n \
+\tst_mtime\t%d\t%d\n \
+\tst_ctime\t%d\t%d\n"
+
+#define LP_STAT_ARGS \
+ \
+(int)state->st_dev, (int)old_state->st_dev, \
+(int)state->st_ino, (int)old_state->st_ino, \
+state->st_mode & 07777, old_state->st_mode & 07777, \
+(int)state->st_nlink, (int)old_state->st_nlink, \
+state->st_uid, old_state->st_uid, \
+state->st_gid, old_state->st_gid, \
+(int)((state->st_rdev >> 8) & 0xff), (int)(state->st_rdev & 0xff), \
+(int)((old_state->st_rdev >> 8) & 0xff), (int)(old_state->st_rdev & 0xff), \
+(unsigned long)state->st_size, (unsigned long)old_state->st_size, \
+(int)state->st_blksize, (int)old_state->st_blksize, \
+(unsigned int)state->st_blocks, (unsigned int)old_state->st_blocks, \
+(int)state->st_atime, (int)old_state->st_atime, \
+(int)state->st_mtime, (int)old_state->st_mtime, \
+(int)state->st_ctime, (int)old_state->st_ctime
+
+extern void check_stat(char *filename, struct stat *state, struct stat *old_state);
+extern void remove_file(char *name);
+extern void remove_file_or_dir(char *name);
+extern void fill_stride(char *buf, int buf_size, long long rank, long long _off);
+
+#endif /* __LP_UTILS_H__ */
#include <errno.h>
#include <liblustre.h>
#include <lustre/lustre_user.h>
-#include <lustre/tests/lp_utils.h>
+#include <lustre/tests/mpi/lp_utils.h>
#define LPGL_FILEN 700000
#define LPGL_TEST_ITEMS 7
if ! echo $PATH | grep -q $LUSTRE/tests; then
export PATH=$PATH:$LUSTRE/tests
fi
- export MDSRATE=${MDSRATE:-"$LUSTRE/tests/mdsrate"}
+ export MDSRATE=${MDSRATE:-"$LUSTRE/tests/mpi/mdsrate"}
[ ! -f "$MDSRATE" ] && export MDSRATE=$(which mdsrate 2> /dev/null)
if ! echo $PATH | grep -q $LUSTRE/tests/racer; then
export PATH=$PATH:$LUSTRE/tests/racer
fi
+ if ! echo $PATH | grep -q $LUSTRE/tests/mpi; then
+ export PATH=$PATH:$LUSTRE/tests/mpi
+ fi
export LCTL=${LCTL:-"$LUSTRE/utils/lctl"}
[ ! -f "$LCTL" ] && export LCTL=$(which lctl)
export LFS=${LFS:-"$LUSTRE/utils/lfs"}